XSLT根据xml中的条件进行修改

时间:2017-08-29 09:38:39

标签: xslt xslt-1.0 xslt-2.0

我有以下输入,我必须使用<price> = <orderitem>更新<name> Desktop <price> <orderitem> <associationid> (出现在xml中的任何位置)与<objectid>具有相同的<associationid>值。

例如,Desktop<objectid><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> ,现在我查找<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> ,其值为2并获取其价格并在此处进行更新。下面的示例输出。

请让我知道解决涉及遍历的问题的方法,我是XSL的新手,并尝试参考XSLT烹饪书和SO,但没有得到适当的参考。感谢。

<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="price[../name='Desktop']">
        <xsl:copy-of select="price[//objectid=.//associationid]" />
    </xsl:template>
</xsl:stylesheet>

输出

npm install -g grunt-cli

XSL:

SqlCommand check = new SqlCommand("SELECT r.RoleName FROM Role r WHERE RoleID IN (SELECT s.RoleID FROM Tbl_Registration s WHERE UserName=@Name AND Password=@pass)", sqlCon);

3 个答案:

答案 0 :(得分:1)

最好使用 key 来解决交叉引用问题:

XSLT 1.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>

答案 1 :(得分:0)

您可以使用密钥:

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

答案 2 :(得分:0)

我注意到你的XSLT中有三件事:

  1. xsl:copy-of中,您目前没有按照您的意图浏览所有价格,因为您需要使用//price
  2. 在这种情况下,您要测试属于价格的元素objectid,因此您应该使用../objectid而不是//objectid
  3. 因此,在您隐含“离开”桌面价格元素的上下文的情况下,您不再可以直接访问.//associationid。但是,您可以使用current()函数来引用该对象(Thanks michael-hor257k
  4. 此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>