使用应用模板进行递归删除

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

我正在尝试转换以下XML文件,以删除每个<AGGREGATION>节点,如果后跟<MULTIPLE>节点。

<?xml version="1.0" encoding="UTF-8"?>
    <RECORD TEMPLATE="PRODUCTS" TRACK="1">
        <FIELD NAME="PRODUCT" BASE="CT300" COUNT="2">
            <AGGREGATION DOMAIN="4" />
            <MULTIPLE TYPE="YES" />
            <MULTIPLE TYPE="YES" />
            <MULTIPLE TYPE="YES" />
            <MULTIPLE TYPE="YES" />
            <MULTIPLE TYPE="YES" />
            <TOKEN TEXT="CT300" BEGIN="11379" END="11384"/>
            <AGGREGATION DOMAIN="9" />
            <AGGREGATION DOMAIN="4" />
            <AGGREGATION DOMAIN="4" />
            <MULTIPLE TYPE="YES" />
            <MULTIPLE TYPE="YES" />
            <MULTIPLE TYPE="YES" />
            <MULTIPLE TYPE="YES" />
            <MULTIPLE TYPE="YES" />
            <TOKEN TEXT="CT300" BEGIN="11379" END="11384"/>
        </FIELD>
    </RECORD>

通过以下xslt转换,我只能删除第一次出现的<AGGREGATION>节点:

<?xml version="1.0" encoding="UTF-8"?>                        
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>   

<xsl:template match="//RECORD[@TEMPLATE='PRODUCTS']/FIELD[@NAME='PRODUCT']/AGGREGATION[following-sibling::*[1][self::MULTIPLE]]">
    <xsl:choose>
        <xsl:when test="//RECORD[@TEMPLATE='PRODUCTS']/FIELD[@NAME='PRODUCT']/AGGREGATION[following-sibling::*[1][self::MULTIPLE]]">
        </xsl:when>
        <xsl:otherwise>
            <xsl:copy>
                <xsl:apply-templates select="@*|node()" />
            </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>  
</xsl:template>

</xsl:stylesheet>

这是我收到的输出:

<?xml version="1.0" encoding="UTF-8"?>
<RECORD TEMPLATE="PRODUCTS" TRACK="1">
        <FIELD BASE="CT300" COUNT="2" NAME="PRODUCT">
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <TOKEN BEGIN="11379" END="11384" TEXT="CT300"/>
            <AGGREGATION DOMAIN="9"/>
            <AGGREGATION DOMAIN="4"/>

            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <TOKEN BEGIN="11379" END="11384" TEXT="CT300"/>
        </FIELD>
   </RECORD>

期望的输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<RECORD TEMPLATE="PRODUCTS" TRACK="1">
        <FIELD BASE="CT300" COUNT="2" NAME="PRODUCT">

            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <TOKEN BEGIN="11379" END="11384" TEXT="CT300"/>             
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <MULTIPLE TYPE="YES"/>
            <TOKEN BEGIN="11379" END="11384" TEXT="CT300"/>
        </FIELD>
 </RECORD>

如何实现<AGGREGATION>节点的递归删除?

xslt xslt-1.0
3个回答
0
投票

我的解决方案如下:

  1. 写一个匹配AGGREGATION的模板。
  2. 是否应该复制任何内容的决定如下: 以第一个跟随兄弟姐妹的名字!= AGGREGATION。 检查它的名字是否是MULTIPLE。 如果是,则不执行任何操作(跳过当前的AGGREGATION元素)。 如果没有,请为当前元素应用模板。
  3. 您还需要身份模板。

所以整个脚本如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="AGGREGATION">
    <xsl:if test="not(following-sibling::*[name()!='AGGREGATION'][1]
      [name()='MULTIPLE'])">
      <AGGREGATION>
        <xsl:apply-templates select="@*|node()"/>
      </AGGREGATION>
    </xsl:if>      
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
  </xsl:template>
</xsl:transform>

有关工作示例,请参阅http://xsltransform.net/bEJaofQ/1


0
投票

只需使用这个空模板加上身份模板有条件地消除不需要的<AGGREGATION>元素:

<xsl:template match="AGGREGATION[following-sibling::*[1] = (self::MULTIPLE or self::AGGREGATION)]" />

0
投票

我想你只需要忽略以下兄弟AGGREGATION元素......

<xsl:template match="RECORD[@TEMPLATE='PRODUCTS']/FIELD[@NAME='PRODUCT']/AGGREGATION[following-sibling::*[not(self::AGGREGATION)][1][self::MULTIPLE]]"/>
© www.soinside.com 2019 - 2024. All rights reserved.