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



我有以下输入,我必须用<name>=Desktop更新<orderitem><price>,用另一个<orderitem>(存在于xml中的任何位置)的<price>更新,该的值与其<objectid>具有相同的<associationid>值。

例如,在这里,我<associationid>为 2 表示Desktop,现在我寻找值为 2 的<objectid>并获取其价格并在此处更新。示例输出如下。

请让我知道解决涉及遍历的此类问题的方法,我是 XSL 的新手,并试图参考 XSLT 食谱和 SO,但没有得到适当的参考。谢谢。

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

XSL:

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

最好使用来解析交叉引用:

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>

你可以使用key:

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

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

  1. xsl:copy-of,您目前没有像预期的那样遍历所有价格,为此您需要使用//price.
  2. 在这种情况下,您要测试属于价格的元素objectid,因此您应该使用../objectid而不是//objectid
  3. 因此,在这种情况下,您
  4. 隐式"离开"桌面价格元素的上下文,因此您不再可以直接访问.//associationid。但是,您可以使用current()函数来引用对象(感谢 michael-hor257k)

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

相关内容

  • 没有找到相关文章

最新更新