xml中基于条件的XSLT修改

xml中基于条件的XSLT修改,xslt,xslt-1.0,xslt-2.0,Xslt,Xslt 1.0,Xslt 2.0,我有下面的输入,我必须用另一个(存在于xml中的任何地方)的的更新的,它的值与其值相同 例如,在这里,我将作为2用于桌面,现在我查找值为2的,获取其价格并在此处更新。下面是示例输出 请让我知道解决这些问题的方法,包括遍历,我对XSL不熟悉,并试图参考XSLT烹饪书等等,但没有得到适当的参考。谢谢 <listoforders> <Orderitem> <name>Desktop</name> <place

我有下面的输入,我必须用另一个
(存在于xml中的任何地方)的
更新
,它的
值与其
值相同

例如,在这里,我将
作为2用于
桌面
,现在我查找值为2的
,获取其价格并在此处更新。下面是示例输出

请让我知道解决这些问题的方法,包括遍历,我对XSL不熟悉,并试图参考XSLT烹饪书等等,但没有得到适当的参考。谢谢

<listoforders>
    <Orderitem>
        <name>Desktop</name>
        <place>NZ</place>
        <price>120ass</price>
        <associationid>2</associationid>
        <Orderitem>
            <name>Desktop2</name>
            <place>NZ</place>
            <price>130</price>
        </Orderitem>
        <Orderitem>
            <name>Desktop3</name>
            <place>NZ</place>
            <price>130obj1</price>
            <objectid>1</objectid>
            <price>130</price>
        </Orderitem>
    </Orderitem>
    <Orderitem>
        <name>laptop</name>
        <place>NZ</place>
        <price>120</price>
        <Orderitem>
            <name>laptop2</name>
            <place>NZ</place>
            <price>130</price>
        </Orderitem>
        <Orderitem>
            <name>laptop3</name>
            <place>NZ</place>
            <price>130obj2</price>
            <objectid>2</objectid>
        </Orderitem>
    </Orderitem>
</listoforders> 

桌面
新西兰
120驴
2.
桌面2
新西兰
130
桌面3
新西兰
130obj1
1.
130
笔记本电脑
新西兰
120
laptop2
新西兰
130
laptop3
新西兰
130obj2
2.
输出

<listoforders>
    <Orderitem>
        <name>Desktop</name>
        <place>NZ</place>
        <price>130obj2</price>
        <associationid>2</associationid>
        <Orderitem>
            <name>Desktop2</name>
            <place>NZ</place>
            <price>130</price>
        </Orderitem>
        <Orderitem>
            <name>Desktop3</name>
            <place>NZ</place>
            <price>130obj1</price>
            <objectid>1</objectid>
            <price>130</price>
        </Orderitem>
    </Orderitem>
    <Orderitem>
        <name>laptop</name>
        <place>NZ</place>
        <price>120</price>
        <Orderitem>
            <name>laptop2</name>
            <place>NZ</place>
            <price>130</price>
        </Orderitem>
        <Orderitem>
            <name>laptop3</name>
            <place>NZ</place>
            <price>130obj2</price>
            <objectid>2</objectid>
        </Orderitem>
    </Orderitem>
</listoforders> 

桌面
新西兰
130obj2
2.
桌面2
新西兰
130
桌面3
新西兰
130obj1
1.
130
笔记本电脑
新西兰
120
laptop2
新西兰
130
laptop3
新西兰
130obj2
2.
XSL:


您可以使用此键:

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

        <xsl:key name="keyitem" match="price" use="../objectid"/>

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

        <xsl:template match="price[../name eq 'Desktop'][../associationid]">
            <xsl:variable name="id" select="../associationid"/>
            <xsl:copy>
            <xsl:value-of select="key('keyitem',$id)"/>
            </xsl:copy>
        </xsl:template>
    </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="*"/>

<xsl:key name="ord" match="Orderitem" use="objectid" />

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

<xsl:template match="price[../name='Desktop']">
    <xsl:copy-of select="key('ord', ../associationid)/price"/>         
</xsl:template>

</xsl:stylesheet>

我注意到XSLT中有三件事:

  • 在的
    xsl:copy中,您当前没有像预期的那样遍历所有价格,因此需要使用
    //price
  • 在这种情况下,您希望测试属于price的元素
    objectid
    ,因此应该使用
    。/objectid
    ,而不是
    //objectid
  • 因此,在这种情况下,您隐式地“离开”桌面price元素的上下文,这样您就不再能够直接访问
    //associationid
    。但是,您可以使用
    current()
    函数引用对象(谢谢)
  • 此XSLT生成所需的输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
        <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="price[../name='Desktop']">
            <xsl:copy-of select="//price[../objectid=current()/../associationid]"/>         
        </xsl:template>
    </xsl:stylesheet>
    
    
    
    另一种可能是使用一个变量来存储id以供以后比较

    <xsl:template match="price[../name='Desktop']">
        <xsl:variable name="var.associationid" select="../associationid"/>
        <xsl:copy-of select="//price[../objectid=$var.associationid]"/>         
    </xsl:template>
    
    
    
    还有什么不同呢?它更短更简单——在你发布你的之前我已经写过了。这就是
    current()
    函数的作用。不过,使用钥匙更优雅、更高效。
    <xsl:template match="price[../name='Desktop']">
        <xsl:variable name="var.associationid" select="../associationid"/>
        <xsl:copy-of select="//price[../objectid=$var.associationid]"/>         
    </xsl:template>