如果 child 节点重复,我该如何删除节点
How do i remove a node if a child node is a duplicate
我正在尝试使用 xslt1 转换 xml。
基本上,如果某个child的child节点已经存在,我想删除一个节点
输入的格式如下:
<Quote>
… lots of data …
<ItemService>
<ID></ID>
…
<Product>
<InternalId>value</InternalId>
<DeliveryInfo>
<lots of subitems>
</Deliveryinfo>
<service>SERVICETEYPE</service>
<some more infos/>
</Product>
…
</Itemservice>
<ItemService>
<ID></ID>
…
<Product>
<InternalId>value</InternalId>
<DeliveryInfo>
<lots of subitems>
</deliveryinfo>
<service>SERVICETEYPE</service>
<some more infos/>
</Product>
…
</ItemService>
… some more data …
</quote>
所以我想删除 <ItemService>
如果另一个具有相同值的 <ItemService>
已经存在。
假设我们有 10 个 ItemServices,其中有 3 个 Product/service 值为 'assembly' 我只想在输出中留下一个(不关心是哪一个)。
我已经尝试了很多东西,但从来没有加起来...
我认为这是正确的方向,有点行不通...
非常感谢任何帮助,xslt 不是我的菜,这个真的让我很烦...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="product" match="Product" use="concat(generate-id(parent::*), service)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ItemService">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="Product[generate-id(.) = generate-id(key('product' , concat(generate-id(parent::*), service))[1])]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果我猜 (!) 正确,你想做类似的事情:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="item-by-service" match="ItemService" use="Product/service" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Quote">
<xsl:copy>
<xsl:apply-templates select="*[not(self::ItemService)]"/>
<!-- keep only distinct items -->
<xsl:apply-templates select="ItemService[generate-id(.) = generate-id(key('item-by-service', Product/service)[1])]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
可以简化为:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="item-by-service" match="ItemService" use="Product/service" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove duplicate items -->
<xsl:template match="ItemService[not(generate-id(.) = generate-id(key('item-by-service', Product/service)[1]))]"/>
</xsl:stylesheet>
重要提示:
XML区分大小写:Service
与service
不一样,</product>
不关闭<Product>
.
我正在尝试使用 xslt1 转换 xml。
基本上,如果某个child的child节点已经存在,我想删除一个节点 输入的格式如下:
<Quote>
… lots of data …
<ItemService>
<ID></ID>
…
<Product>
<InternalId>value</InternalId>
<DeliveryInfo>
<lots of subitems>
</Deliveryinfo>
<service>SERVICETEYPE</service>
<some more infos/>
</Product>
…
</Itemservice>
<ItemService>
<ID></ID>
…
<Product>
<InternalId>value</InternalId>
<DeliveryInfo>
<lots of subitems>
</deliveryinfo>
<service>SERVICETEYPE</service>
<some more infos/>
</Product>
…
</ItemService>
… some more data …
</quote>
所以我想删除 <ItemService>
如果另一个具有相同值的 <ItemService>
已经存在。
假设我们有 10 个 ItemServices,其中有 3 个 Product/service 值为 'assembly' 我只想在输出中留下一个(不关心是哪一个)。
我已经尝试了很多东西,但从来没有加起来...
我认为这是正确的方向,有点行不通...
非常感谢任何帮助,xslt 不是我的菜,这个真的让我很烦...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="product" match="Product" use="concat(generate-id(parent::*), service)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ItemService">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="Product[generate-id(.) = generate-id(key('product' , concat(generate-id(parent::*), service))[1])]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果我猜 (!) 正确,你想做类似的事情:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="item-by-service" match="ItemService" use="Product/service" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Quote">
<xsl:copy>
<xsl:apply-templates select="*[not(self::ItemService)]"/>
<!-- keep only distinct items -->
<xsl:apply-templates select="ItemService[generate-id(.) = generate-id(key('item-by-service', Product/service)[1])]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
可以简化为:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="item-by-service" match="ItemService" use="Product/service" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove duplicate items -->
<xsl:template match="ItemService[not(generate-id(.) = generate-id(key('item-by-service', Product/service)[1]))]"/>
</xsl:stylesheet>
重要提示:
XML区分大小写:Service
与service
不一样,</product>
不关闭<Product>
.