1

この入力がある場合:

<root> 
    <library id="L1">
        <shelf1 id="1">
            <book id="1" category="science">
                <attributes>                    
                    <year>2000</year>
                </attributes>
                <attributes>
                    <author>xx</author>
                    <year>2010</year>
                    <isbn>001</isbn>
                </attributes>
                <attributes>
                    <author>yy</author>
                    <publisher>zz</publisher>
                    <isbn>002</isbn>
                </attributes>
                <other>y</other>
            </book>  
            <book id="2" category="science">
                ...
            </book>
        </shelf1>

        <shelf2>...</shelf2>
    </library>
</root>

期待される出力:

<root> 
    <library id="L1">
        <shelf1 id="1">
            <book id="1" category="science">
                <attributes>
                    <author>yy</author>                    
                    <publisher>zz</publisher>
                    <isbn>002</isbn>
                    <year>2010</year>
                </attributes>
                <other>y</other>
            </book>  
            <book id="2" category="science">
                ...
            </book>
        </shelf1>

        <shelf2>...</shelf2>
    </library>
</root>

要素の「属性」を組み合わせる必要があります。2 つ以上の属性が存在する場合、属性の子が以前に存在しなかった場合は、子を新しい情報として保持しますが、以前に存在した場合は単に最新の値を使用します。

XSLT 1.0 または 2.0 でこのような変換を行うにはどうすればよいですか?ご協力ありがとうございます。

ジョン

4

1 に答える 1

2

この変換 (XSLT 2.0):

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

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

 <xsl:template match="book[attributes]">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <attributes>
      <xsl:for-each-group select="attributes/*" group-by="name()">
        <xsl:sort select="current-grouping-key()"/>
        <xsl:apply-templates select="."/>
      </xsl:for-each-group>
    </attributes>
    <xsl:apply-templates select="*[not(self::attributes)]"/>
  </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントに適用した場合:

<root>
    <library id="L1">
        <shelf1 id="1">
            <book id="1" category="science">
                <attributes>
                    <year>2000</year>
                </attributes>
                <attributes>
                    <author>xx</author>
                    <year>2010</year>
                    <isbn>001</isbn>
                </attributes>
                <attributes>
                    <author>yy</author>
                    <publisher>zz</publisher>
                    <isbn>002</isbn>
                </attributes>
                <other>y</other>
            </book>
            <book id="2" category="science">
            ...
            </book>
        </shelf1>
        <shelf2>...</shelf2>
    </library>
</root>

必要な正しい結果が生成されます

<root>
      <library id="L1">
            <shelf1 id="1">
                  <book id="1" category="science">
            <attributes>
               <author>xx</author>
               <isbn>001</isbn>
               <publisher>zz</publisher>
               <year>2000</year>
            </attributes>
            <other>y</other>
         </book>
                  <book id="2" category="science">
            ...
            </book>
            </shelf1>
            <shelf2>...</shelf2>
      </library>
</root>

説明:

  1. アイデンティティ ルールの適切な使用とオーバーライド。

  2. xsl:for-each-group属性を持つXSLT 2.0 命令の適切な使用group-by

  3. XSLT 2.0 関数current-grouping-key()と XPath 関数の適切な使用name()

于 2012-07-11T04:34:49.503 に答える