如何将这个子元素一起使用XSLT结合? [关闭](How to combine this chi

2019-10-16 23:58发布

如果我有这样的输入:

<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>

expetced输出:

<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>

我需要的元素“属性”结合在一起。 如果存在两个或多个属性,当属性的孩子从未存在,我们保住孩子作为新的信息,但如果它以前存在的,我们简单地使用最新的值。

如何在XSLT 1.0或2.0做这样的转型?非常感谢您的帮助。

约翰

Answer 1:

这种变换(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. 正确使用XSLT 2.0指令xsl:for-each-group具有属性group-by

  3. 正确使用XSLT 2.0函数的current-grouping-key()并且XPath函数name()



文章来源: How to combine this child element together using XSLT? [closed]
标签: xml xslt