使用xslt清除xml的所有子节点和节点值

时间:2017-05-23 13:11:46

标签: xml xslt

是否有人知道如何使用xslt转换删除xml中所有子节点的内容。

源代码

  <TotalResponse id="TE2146D7766F24FE683090325091EE0B4">
     <TotalCovIA27_CrimeResponse id="T8550FBBC76364CA699158D4087059F9A">
          <CovIA27_CrimeResponse>
            <instance>
              <CovGroupType>i8BE0F604FF6F44AEB3C36271DCBB7204</CovGroupType>
              <CovID>r67F85BB6345E4D3893C25D1B47FA7E32</CovID>
              <CovType>add</CovType>
            </instance>
          </CovIA27_CrimeResponse>
        </TotalCovIA27_CrimeResponse>
        <TotalCovIA28_CrimeResponse id="T257F4902E7214C58ABD9258860CB6C24">
          <CovIA28_CrimeResponse>
            <instance>
              <CovGroupType>i2880CCCAB9D045A3A7FFFCB6AE0C05C7</CovGroupType>
              <CovID>rED310B0934534A8BA1CA2B5CB0BA77E5</CovID>
              <CovType>modify</CovType>
            </instance>
            <change>
              <ChangeFieldID>IA28ForgeryAndAlterationInput.Limit</ChangeFieldID>
              <ChangeNewValue>131334</ChangeNewValue>
            </change>
          </CovIA28_CrimeResponse>
        </TotalCovIA28_CrimeResponse>

  </TotalResponse>

预期输出1

<TotalResponse id="TE2146D7766F24FE683090325091EE0B4">
     <TotalCovIA27_CrimeResponse id="T8550FBBC76364CA699158D4087059F9A">
          <CovIA27_CrimeResponse>
            <instance>
              <CovGroupType></CovGroupType>
              <CovID></CovID>
              <CovType></CovType>
            </instance>
          </CovIA27_CrimeResponse>
        </TotalCovIA27_CrimeResponse>
        <TotalCovIA28_CrimeResponse id="T257F4902E7214C58ABD9258860CB6C24">
          <CovIA28_CrimeResponse>
            <instance>
              <CovGroupType></CovGroupType>
              <CovID></CovID>
              <CovType></CovType>
            </instance>
            <change>
              <ChangeFieldID></ChangeFieldID>
              <ChangeNewValue></ChangeNewValue>
            </change>
          </CovIA28_CrimeResponse>
        </TotalCovIA28_CrimeResponse>

  </TotalResponse>

预期输出2

<TotalResponse id="TE2146D7766F24FE683090325091EE0B4">
     <TotalCovIA27_CrimeResponse id="T8550FBBC76364CA699158D4087059F9A">
          <CovIA27_CrimeResponse>
            <instance\>  
          </CovIA27_CrimeResponse>
        </TotalCovIA27_CrimeResponse>
        <TotalCovIA28_CrimeResponse id="T257F4902E7214C58ABD9258860CB6C24">
          <CovIA28_CrimeResponse>
            <instance/>                               
            <change/>  
          </CovIA28_CrimeResponse>
       </TotalCovIA28_CrimeResponse>
  </TotalResponse>

输出都满足我的要求,但我更喜欢输出1。

注意:总响应是动态父根名称,它根据其他xslt的输出而变化。

2 个答案:

答案 0 :(得分:0)

正如我所见,你想为孩子们提供“特殊待遇” instancechange元素。

在第一个版本中,您只想保留标签 它们的内容和第二个变体省略了这些元素 共

所以第一种情况的解决方案是模板匹配 instancechange的子元素无论它们是什么。 此模板的内容应仅包含<xsl:copy/>, 即只制作这些元素的浅拷贝

脚本还必须包含身份模板。

下面是第一个变体的解决方案:

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

  <xsl:template match="instance/* | change/*">
    <xsl:copy/>
  </xsl:template>

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

工作原理:

让我们从最后开始 - 身份模板match="node() | @*")。 它将所有源内容复制到输出。 这是“最通用”的模板,为所有未被其他节点服务的节点提供服务 (更具体)模板。有关详细信息,请在网上搜索。

现在转到匹配"instance/* | change/*"的模板。 match子句包含两部分:instance/*change/* 上面用 XPath 表达式用| sum 运算符)分隔。

这意味着:此模板将为每个元素提供服务 instance的孩子或change的孩子(以及身份模板 上述描述不会(不适用于)他们)。

现在转到此模板的内容:<xsl:copy/>。 此命令执行所谓的浅拷贝,即它应对 只输出一个空的“原始”标签。 例如。源元素<CovID>r67F8...7E32</CovID>将输出为 <CovID/>。有关详细信息,您还可以在网上搜索。

关于细节的另一个评论:

如果你尝试过这个脚本而且你很敏锐,那么你可能已经注意到了<CovID></CovID>输出包含<CovID/>

没问题,从“XML的角度来看”这是相同的,但更短。 这就是(我想所有)XSLT处理器生成的方式 空元素。

如果你想收到预期输出2 (你的第二个版本), 然后从匹配子项的模板中删除<xsl:copy/> instancechange

实际上,您可以更简洁地编写此模板:

<xsl:template match="instance/* | change/*"/>

所以你得到什么都不做模板。

答案 1 :(得分:0)

  

如何删除xml中所有子节点的内容

目前尚不清楚“子节点”是什么意思。看起来您只想从输入中删除所有文本节点 - 这很容易使用:

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:template match="@*|*">
    <xsl:copy>
        <xsl:apply-templates select="@*|*"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

这只是复制元素及其属性,并丢弃任何其他类型的节点。