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如果两个产品的某个标签包含相同的值,这会是一个问题吗?我不确定在这种情况下是否会发生冲突。请指导。提前致谢。

4

2 回答 2

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

于 2013-07-12T06:14:25.963 回答
0

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

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

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

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

如果 Img* 标记的名称众所周知,您也可以试试这个:

<xsl:key name="keyImg" match="Img1 | Img2 | Img2 | Img4"
             use="concat(../ID, '|', .)"/>
于 2013-07-12T06:14:36.643 回答