Xslt 对于包含两个属性的所有节点,将两个属性的值连接到一个属性中

Xslt 对于包含两个属性的所有节点,将两个属性的值连接到一个属性中,xslt,Xslt,我有这样的XML: <Parent> <Elem1 Attr1="1" Attr2="2"> <Elem2> <Elem3 Attr1="4" Attr2="5"></Elem3> </Elem2> </Elem1> </Parent> 它应该变成这样: <Parent&g

我有这样的XML:

   <Parent>
       <Elem1 Attr1="1" Attr2="2">
           <Elem2>
               <Elem3 Attr1="4" Attr2="5"></Elem3>
           </Elem2>
       </Elem1>
   </Parent>

它应该变成这样:

  <Parent>
     <Elem1 Attr1="1+2">
        <Elem2>
           <Elem3 Attr1="4+5"></Elem3>
        </Elem2>
     </Elem1>
  </Parent>

问题是我不知道元素的名称,即在本例中是
Elem1
Elem3
。我知道元素必须同时包含属性
Attr1
和属性
Attr2
,但不能提前包含所有这样的元素名

我还知道父元素的名称必须是
parent
,但是包含属性的子元素可以是任何级别的,可以是直接的子元素,也可以是父树中更深的子元素

我能找到的最接近可能的解决方案是
但是我的XSLT知识还不足以让它适应这种情况。

我想您应该做一些类似的事情:

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="@Attr1[../@Attr2]">
    <xsl:attribute name="Attr1">
        <xsl:value-of select="."/>
        <xsl:text>+</xsl:text>
        <xsl:value-of select="../@Attr2"/>
    </xsl:attribute>
</xsl:template>

<xsl:template match="@Attr2[../@Attr1]"/>

</xsl:stylesheet>

+

我想你应该做以下事情:

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="@Attr1[../@Attr2]">
    <xsl:attribute name="Attr1">
        <xsl:value-of select="."/>
        <xsl:text>+</xsl:text>
        <xsl:value-of select="../@Attr2"/>
    </xsl:attribute>
</xsl:template>

<xsl:template match="@Attr2[../@Attr1]"/>

</xsl:stylesheet>

+

解决这个问题的一个方法是

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">


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

    <xsl:template match="Parent//*[@Attr1 and @Attr2]/@Attr1">
        <xsl:attribute name="Attr1" select="concat(., '+', ../@Attr2)"/>
    </xsl:template>

    <xsl:template match="Parent//*[@Attr1 and @Attr2]/@Attr2"/>

</xsl:transform>


解决这个问题的一个方法是

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">


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

    <xsl:template match="Parent//*[@Attr1 and @Attr2]/@Attr1">
        <xsl:attribute name="Attr1" select="concat(., '+', ../@Attr2)"/>
    </xsl:template>

    <xsl:template match="Parent//*[@Attr1 and @Attr2]/@Attr2"/>

</xsl:transform>


在两个正确答案之间进行选择是一个艰难的选择。我更喜欢这个,因为它更优雅、更完整的w.r.t父节点,但我不知道我的环境到现在还不支持XSLT2.0,所以应该相应地标记这个问题。所以我考虑到迈克尔的回答是更早的。谢谢。在两个正确的答案之间做出选择是很困难的。我更喜欢这个,因为它更优雅、更完整的w.r.t父节点,但我不知道我的环境到现在还不支持XSLT2.0,所以应该相应地标记这个问题。所以我考虑到迈克尔的回答是更早的。非常感谢。