xslt在多个节点中分组

时间:2013-07-12 05:44:12

标签: xslt xslt-1.0

我的输入xml的示例结构如下所示:

    <Products>
  <Product>
    <ID>Product1</ID>
    <Extra1></Extra1>
    <Extra2></Extra2>
    <Img1>val1</Img1>
    <Img2>val2</Img2>
    <Img3>val2</Img3>
    <Img4>val1</Img4>
  </Product>

  <Product>
    <ID>Product2</ID>
    <Extra1></Extra1>
    <Extra2></Extra2>
    <Img1>val1</Img1>
    <Img2>val2</Img2>
    <Img3>val2</Img3>
    <Img4>val1</Img4>
  </Product>
</Products>

我一次解析每个product元素,并按照其值对每个产品的Img标记进行分组。我正在使用<xsl:key name="keyImg" match="Product/*[contains(local-name(), 'Img')]" use="."/>。但是一遍又一遍地使用相同的密钥。如果两个产品包含某些Img标记的相同值,是否会出现问题?我不确定在这种情况下是否会有冲突。请指导。提前谢谢。

2 个答案:

答案 0 :(得分:0)

使用两部分键,如下所示:

<xsl:key 
  name="keyImg" 
  match="Product/*[starts-with(name(), 'Img')]" 
  use="concat(generate-id(..), '-', .)" 
/>

<xsl:template match="Product">
  <xsl:variable name="productID" select="generate-id()" />

  <xsl:for-each select="*[starts-with(name(), 'Img')][
    generate-id() = generate-id(key(concat($productID, '-', .)))
  ]">
    <!-- ... --->
  </xsl:for-each>
</xsl:template>

总的来说,如果具有相同语义值(Img)的节点具有不同的名称(Img1Img2等),则不理想。如果您可以对此进行任何操作,只需将它们命名为Img

答案 1 :(得分:0)

问。 但是一遍又一遍地使用相同的密钥。如果两个产品包含某些Img标签的相同值,那么它会成为一个问题吗?我不确定在这种情况下是否会有冲突。

是否存在“冲突”取决于想要的结果。您的密钥包含列表中具有相同值的所有Img *项目。使用此键,您可以生成所有Img *值的唯一列表。

如果密钥对于一个产品中的Img *值应该是唯一的,您可以将generate-id()或“产品/ ID”添加到密钥。 像这样:

<xsl:key name="keyImg" match="Product/*[starts-with(local-name(), 'Img')]"
             use="concat(../ID, '|', .)"/>

如果Img * tages的名称众所周知,您也可以尝试:

<xsl:key name="keyImg" match="Img1 | Img2 | Img2 | Img4"
             use="concat(../ID, '|', .)"/>