如果一个子节点是重复的,我如何删除一个节点?

问题描述 投票:0回答:1

我想用xslt1来转换一个xml,基本上,我想删除一个节点,如果某个子节点已经存在的话。

基本上,我想删除一个节点,如果某个子节点的子节点已经存在,输入的格式是这样的。

<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个产品服务的值是'装配',我希望在输出中只留下一个(不在乎是哪一个)。

我试过很多方法,但总是无法加起来......。

我认为这个方向是对的,但却没有用......。

任何帮助都是非常感激的,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>

xml xslt xslt-1.0
1个回答
0
投票

如果我猜得没错的话(!),你要做的是这样的事情。

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>

可以简化为: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>

<!-- 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>.

© www.soinside.com 2019 - 2024. All rights reserved.