我有以下XML,我正在尝试根据名称子节点获取唯一的节点。
原始XML:
<products>
<product>
<name>White Socks</name>
<price>2.00</price>
</product>
<product>
<name>White Socks/name>
<price>2.00</price>
</product>
<product>
<name>Blue Socks</name>
<price>3.00</price>
</product>
</products>
我想要的是:
<products>
<product>
<name>White Socks</name>
<price>2.00</price>
</product>
<product>
<name>Blue Socks</name>
<price>3.00</price>
</product>
</products>
我尝试了各种各样但不值得列出的内容,我得到的最接近的是使用XPath,但刚刚返回如下名称。但是,这是错误的,因为我想要上面的完整XML,而不仅仅是节点值。
White Socks
Blue Socks
我正在使用Ruby并试图像这样迭代节点:
@doc.xpath("//product").each do |node|
显然上面目前获得所有产品节点,而我想要所有独特的产品节点(使用子节点“name”作为唯一标识符)
答案 0 :(得分:1)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kProdByName" match="product"
use="name"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"product
[not(generate-id()
=
generate-id(key('kProdByName',name)[1])
)
]"/>
</xsl:stylesheet>
应用于提供的XML文档(更正为格式良好):
<products>
<product>
<name>White Socks</name>
<price>2.00</price>
</product>
<product>
<name>White Socks</name>
<price>2.00</price>
</product>
<product>
<name>Blue Socks</name>
<price>3.00</price>
</product>
</products>
会产生想要的正确结果:
<products>
<product>
<name>White Socks</name>
<price>2.00</price>
</product>
<product>
<name>Blue Socks</name>
<price>3.00</price>
</product>
</products>
请注意:
identity rule “按原样”复制每个节点。
有一个覆盖模板可以排除任何不属于其组中第一个的product
元素。
XPath-one-liner (注意这是O(N ^ 2) - 在许多product
元素上非常慢):
/*/product[not(name = following-sibling::product/name)]
答案 1 :(得分:0)
使用XSLT,您可以使用Muenchian分组来消除重复项,如下所示:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="prod-by-name" match="product" use="name"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="product[not(generate-id() = generate-id(key('prod-by-name', name)[1]))]"/>
</xsl:stylesheet>