如果子行包含特定元素,则删除该行,但不删除下面的内容

时间:2018-07-16 12:16:06

标签: xml xslt parent-child

我正在尝试通过以下方式更改XML布局:

每当代码中的节点后跟具有Product UserTypeID的子项(换句话说,直接子项不包含任何属性,那么我想删除“ OBJ_TEST_5”。但是,我仍然要保留内容有属性的孩子!

原始XML:

  <Products>
    <Product ID="B5_123123" UserTypeID="OBJ_TEST_5" ParentID="OBJ_TEST_4">
      <Product ID="CB_1233434" UserTypeID="OBJ_childBelow" ParentID="OBJ_TEST_5">
        <Product ID="GCB_9162375" UserTypeID="OBJ_grandChildBelow">
          <Values>
            <Value AttributeID="TESTATTR">Classification 1 root/ Gelbe Struktur/ G1_222338/ / / </Value>
            <Value AttributeID="TESTATTR2">TRIAL retrans</Value>
            <Value AttributeID="TESTATTR3">TRIAL2</Value>
          </Values>
        </Product>
      </Product>
    </Product>
  </Products>

使用XSLT进行了调整:

  <Products>
        <Product ID="GCB_9162375" UserTypeID="OBJ_grandChildBelow">
          <Values>
            <Value AttributeID="TESTATTR">TRIAL1</Value>
            <Value AttributeID="TESTATTR2">TRIAL2 retrans</Value>
            <Value AttributeID="TESTATTR3">TRIAL3</Value>
          </Values>
        </Product>
      </Product>
    </Product>
  </Products>

我目前拥有的XSLT包括:

<xsl:template match="Product[@UserTypeID='OBJ_TEST_5']">
      <xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="Product[@UserTypeID='OBJ_childBelow']">
      <xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="Product[@UserTypeID='OBJ_grandChildBelow']">
      <xsl:apply-templates select="*"/>
</xsl:template>

但是,这似乎删除了所有内容!

你们中的任何一个可以帮我吗?

1 个答案:

答案 0 :(得分:0)

如果这些是XSLT中唯一的模板,那么您还需要添加身份模板

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

或者在XSLT 3.0中,执行此操作...

<xsl:mode on-no-match="shallow-copy"/> 

对于您现有的模板,您不希望与“ OBJ_grandChildBelow”匹配的模板,因为您不想删除该模板。其他两个模板可能也可以组合成一个通用的模板。

<xsl:template match="Product[not(Values)]">
  <xsl:apply-templates />
</xsl:template>

尝试使用此XSLT

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

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

  <xsl:template match="Product[not(Values)]">
    <xsl:apply-templates />
  </xsl:template>
</xsl:stylesheet>