我的输入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
标签包含相同的值,这会是一个问题吗?我不确定在这种情况下是否会发生冲突。请引导。提前谢谢。
使用由两部分组成的密钥,如下所示:
<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
)的节点具有不同的名称(Img1
、Img2
等),这是不理想的。如果你能做些什么,就把它们命名为Img
。
Q 但同一把钥匙被反复使用。如果两个产品包含相同的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, '|', .)"/>