我有一个我正在尝试转换的XML,其中包含不同节点之间的关系,通过ID相关,但我无法弄清楚如何将它们“粘合”在一起。
XML示例:
<order>
<products>
<product id="1234">
<item quantity="5" colour="red">
<item quantity="2" colour="blue">
</product>
<product id="9876">
<item quantity="10" colour="teal">
</product>
</products>
<prices>
<productprice>
<refProduct id="1234" />
<price gross="9.99" />
</productprice>
<productprice>
<refProduct id="9876" />
<price gross="6.89" />
</productprice>
</prices>
</order>
我希望的结果是能够通过for-each显示产品,并在它们旁边列出各自的价格。
感激地收到了任何线索。
编辑:固定叛徒产品元素,例子应该是格式良好的答案 0 :(得分:1)
以下是进行所需连接的简单概念验证。输入XML没有很好地形成,所以我假设只有一个产品元素,有多个产品子元素。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<products>
<xsl:for-each select="order/products/product">
<product>
<xsl:variable name="productid" select="@id"/>
<xsl:attribute name="id">
<xsl:value-of select="$productid"/>
</xsl:attribute>
<xsl:attribute name="price">
<xsl:value-of
select="/order/prices/productprice[refProduct[@id = $productid]]/price/@gross"/>
</xsl:attribute>
</product>
</xsl:for-each>
</products>
</xsl:template>
</xsl:stylesheet>
它产生以下输出:
<?xml version="1.0" encoding="utf-8"?>
<products>
<product id="1234" price="9.99"/>
<product id="9876" price="6.89"/>
</products>
答案 1 :(得分:0)
您的XML格式不正确,这使得很难准确回答这个问题。但是有些事情可能就是这样吗?
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<out>
<xsl:apply-templates/>
</out>
</xsl:template>
<xsl:template match="/root/order/products/product">
<xsl:variable name="id" select="string(@id)" />
<prod id="{@id}">
<xsl:value-of select="/root/prices/productprice[refProduct/@id=$id]/price/@gross" />
</prod>
</xsl:template>
</xsl:stylesheet>
显然,根据XML的结构,确切的XPath会有所不同,但是这样的东西会匹配产品与价格。如果您需要迭代产品,可以将其移动到函数中。
答案 2 :(得分:0)
在查找元素方面,这是使用 xsl:key 的理想情况。因此,对于您的样本,您可能希望查找产品的价格,因此您可以像这样定义密钥
<xsl:key name="prices" match="productprice" use="refProduct/@id" />
因此,这将允许您使用产品ID的值访问 productprice 元素。具体来说,如果您定位在产品元素上,则可以访问该密钥以获得总价格,如下所示:
<xsl:value-of select="key('prices', @id)/price/@gross" />
至于展示产品,一般来说,通常最好使用 xsl:apply-templates 而不是 xsl:for-each ,因为它更像是在'精神'中XSLT。
<xsl:apply-templates select="products/product" />
可以在多个地方调用模板以减少代码重复,并且可以使代码更具可读性,尤其是通过减少代码缩进。
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="prices" match="productprice" use="refProduct/@id" />
<xsl:template match="/order">
<table>
<xsl:apply-templates select="products/product" />
</table>
</xsl:template>
<xsl:template match="product">
<tr>
<td><xsl:value-of select="@id" /></td>
<td><xsl:value-of select="key('prices', @id)/price/@gross" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
应用于以下格式良好的XML
<order>
<products>
<product id="1234">
<item quantity="5" colour="red"/>
<item quantity="2" colour="blue"/>
</product>
<product id="9876">
<item quantity="10" colour="teal"/>
</product>
</products>
<prices>
<productprice>
<refProduct id="1234"/>
<price gross="9.99"/>
</productprice>
<productprice>
<refProduct id="9876"/>
<price gross="6.89"/>
</productprice>
</prices>
</order>
以下是输出
<table>
<tr>
<td>1234</td>
<td>9.99</td>
</tr>
<tr>
<td>9876</td>
<td>6.89</td>
</tr>
</table>