68572


お手数ですが、お知恵いただきたく投稿させていただきました。  
元となるxml構造の表で列数定義やセルの連結情報がないため、正しい列数が算出できず困っています。

**やったこと**  
1\. XSL1.0で各行のセル数は拾い、羅列したものの、その値をから行の最大値を比較できず断念。  
2\. XSL2.0でテンポラリーツリーで配列を使い値を比較。...が、経験値が浅く、かつ参考が少ないため解決策模索。（←現在）

環境：saxonb9-1-0-8j、JavaSEランタイム1.8.0、Windows10（1903）

**やりたいこと**  
xslで表の各行（row）にあるセル（entry）数をカウントし、カウントした各行の値を比較し一番多いセルの数（最大値）を結果に出す。  
※行数・列数は固定されない前提です。  
※元となるxmlにセル数を追記しました。（ここで求めたい結果はセル数4）

**元となるxml**

[code]

    <table tocentry = "1">
        <table.group charoff = "50" align = "left">
            <table.body valign = "top">
                セル数2：<row><entry valign = "middle" align = "center">000-00</entry><entry valign = "middle" align = "center">西海岸</entry></row>
                セル数4：<row><entry valign = "top">999-01</entry><entry valign = "top">海</entry><entry valign = "top">-</entry><entry valign = "top">-</entry></row>
                セル数4：<row><entry valign = "top">999-02</entry><entry valign = "top">海</entry><entry valign = "top">-</entry><entry valign = "top">-</entry></row>
                セル数3：<row><entry valign = "top">123-45</entry><entry valign = "top">北海</entry><entry valign = "top">-</entry></row>
                セル数2：<row><entry valign = "middle" align = "center">678-90</entry><entry valign = "middle" align = "center">南海</entry></row>
            </table.body>
        </table.group>
    </table>
    
[/code]

**XSLT内容（XSL2.0）**  
調整途中のため、間違っているところや汚いところもあるとおもいますがソースを記載させていただきます。

[code]

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                                    xmlns:xlink = "http://www.w3.org/1999/xlink"
                                    xmlns:rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                                    xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
                                    xmlns:xs = "http://www.w3.org/2001/XMLSchema">
    <xsl:output method="xml" version="1.0" indent="no" encoding="UTF-8" />
    
    <xsl:template match="table/table.group">
        <xsl:variable name="cols-count" as="element()*">
            <xsl:for-each select=".//row">
                <xsl:variable name="i" select="position()" as="xs:integer"/>
                <xsl:element name="array{$i}"><xsl:value-of select="count(.//entry)"/></xsl:element>
            </xsl:for-each>
        </xsl:variable>
        <table>
            <xsl:attribute name="tabletype">all</xsl:attribute>
            <xsl:attribute name="format">all</xsl:attribute>
            <xsl:attribute name="cols"><xsl:value-of select="$cols-count[0]"/></xsl:attribute>
            <xsl:attribute name="width">100%</xsl:attribute>
            <!--<xsl:call-template name="cols-count" />-->
            <xsl:apply-templates />
        </table>
    </xsl:template>
    
    <xsl:template match="table.head">
        <thead>
            <xsl:apply-templates/>
        </thead>
    </xsl:template>
    
    <xsl:template match="table.body">
        <tbody>
            <xsl:apply-templates />
        </tbody>
    </xsl:template>
    
    <xsl:template match="row">
        <tr><xsl:apply-templates/></tr>
    </xsl:template>
    
    <xsl:template match="entry">
        <td>
            <xsl:if test="@hspan"><xsl:attribute name="hspan"><xsl:value-of select="@hspan" /></xsl:attribute></xsl:if>
            <xsl:if test="@vspan"><xsl:attribute name="vspan"><xsl:value-of select="@vspan" /></xsl:attribute></xsl:if>
            <xsl:if test="@rotate"><xsl:attribute name="rotate"><xsl:value-of select="@rotate" /></xsl:attribute></xsl:if>
            <p><xsl:apply-templates /></p>
        </td>
    </xsl:template>
    
[/code]


CC BY-SA 4.0
2020-07-13T03:04:31.603
68537
2020-07-14T02:52:12.780
2020-07-13T08:56:47.127
24763
24763
question
xsl xslt
xslで表の各行にあるセル（entry）数をカウントし、その値を各行比較して一番多い値を結果に出す


お問い合わせでやりたいことはCALSテーブルでいうところの、`tgroup/@cols`を求めたいことだと思います．

コード中の

[code]

    <xsl:attribute name="cols"><xsl:value-of select="$cols-count[0]"/></xsl:attribute>
    
[/code]

の代わりに

[code]

    <xsl:attribute name="cols" select="max(for $row in table.body/row return(count($row/entry)))"/>
    
[/code]

ではいかがでしょうか？

手元のOxygen Developerで変換してみた結果は、以下のように`cols="4"`で出力されます．

[code]

    <table xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" tabletype="all" format="all" cols="4" width="100%">
    
[/code]

一度お試しください．

蛇足ですが、`saxonb9-1-0-8j`はXSLT 2.0の初期実装です．最新のSaxonだとXSLT 3.0も使えて大変お得です．

以上


CC BY-SA 4.0
2020-07-14T02:52:12.780
68572
2020-07-14T02:52:12.780
9503
68537
answer