0

これに似た質問/回答が他にもいくつかあることは知っていますが、この変換に関する私の混乱に対処するものを読んだことがありません。この形式から XML ドキュメントを移動する必要があります。

<root>
    <row>
        <t0>1</t0>
        <title>Main Title</title>
    </row>
    <row>
        <t0>2</t0>
        <title>Secondary Title</title>
        <note>Note</note>
    </row>
    <row>
        <t0>3</t0>
        <title>Tertiary Title</title>
    </row>
    <row>
        <t0>3</t0>
        <title>Another Title</title>
    </row>
    <row>
        <t0>2</t0>
        <title>A Second Secondary Title</title>
        <note>Note</note>
    </row>
    <row>  
        <t0>3</t0>
        <title>Third Level Title</title>
    </row>
    <row> 
        <t0>3</t0>
        <title>Title at Level Three</title>
    </row>
</root>

この形式に:

<root>
    <header>List</header>
    <t01>
        <title>Main Title</title>
        <t02>
            <title>Secondary Title</title>
            <note>Note</note>
            <t03>
                <title>Tertiary Title</title>
            </t03>
            <t03>
                <title>Another Title</title>
            </t03>
        </t02>
        <t02>
            <title>A Second Secondary Title</title>
            <note>Note</note>
            <t03>
                <title>Third Level Title</title>
            </t03>
            <t03>   
                <title>Title at Level Three</title>
            </t03>
        </t02>
    </t01>
</root>

XSLT 2.0 を使用していますが、for-each-group を再帰的に適用することに行き詰まっています。お時間とご迷惑をおかけしてありがとうございます。

4

2 に答える 2

2

XSLT 2.0ではfor-each-grouping、再帰関数またはテンプレートと一緒に使用することを強くお勧めします。以下は、関数を使用したサンプルです。

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf">

<xsl:output indent="yes"/>

<xsl:function name="mf:group" as="element()*">
  <xsl:param name="elements" as="element(row)*"/>
  <xsl:param name="level" as="xs:integer"/>
  <xsl:for-each-group select="$elements" group-starting-with="row[t0 = $level]">
    <xsl:element name="t{format-number($level, '00')}">
      <xsl:copy-of select="* except t0"/>
      <xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
    </xsl:element>
  </xsl:for-each-group>
</xsl:function>

<xsl:template match="root">
  <xsl:copy>
    <header>List</header>
    <xsl:sequence select="mf:group(row, 1)"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>
于 2013-01-15T16:57:24.900 に答える
1

これを試してください:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/root">
    <root>
      <header>List</header>
      <xsl:apply-templates select="row[t0 = 1]" />
    </root>
  </xsl:template>

  <xsl:template match="row">
    <xsl:variable name="level" select="t0" />

    <xsl:element name="{concat('t0', $level)}">
      <xsl:apply-templates select="title | note" />
      <xsl:variable name="nextPeer" 
            select="following-sibling::row[t0 &lt;= $level]" />
      <xsl:variable name="children" 
            select="following-sibling::row[t0 = $level + 1][not($nextPeer) 
                 or (count(preceding-sibling::row) &lt; count($nextPeer[1]/preceding-sibling::row))]" />

      <xsl:apply-templates select="$children" />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>
于 2013-01-15T16:18:11.353 に答える