1

我有一个我正在尝试转换的 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 展示产品,并在旁边列出各自的价格。

感激地收到任何线索。

编辑:固定的叛徒产品元素,示例应该是正确的

4

3 回答 3

1

这是一个简单的概念证明,用于建立您想要的连接。输入 XML 格式不正确,因此我假设只有一个 products 元素,具有多个 product 子元素。

<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>
于 2012-08-21T16:43:25.253 回答
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>

显然,确切的 XPath 会根据您的 XML 结构的不同而有所不同,但是这样的东西会使产品与价格相匹配。如果您确实需要迭代产品,您可以将其移出到函数中。

于 2012-08-21T16:52:52.640 回答
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>
于 2012-08-21T16:54:21.303 回答