xsl transform删除双标签

时间:2014-06-11 13:30:17

标签: xslt

我有som XML我需要转换以删除双标签。

最初我用过:

<xsl:template match="*[name()=name(../..)]"></xsl:template>
<xsl:template match="*[name()=name(../../..)]"></xsl:template>
<xsl:template match="*[name()=name(..)]">
    <xsl:apply-templates select="@*|node()"/>
</xsl:template>

它们一起删除了两个具有相同名称的标签的内部。但是,只有只有一个内部标签才能正常工作。

我有:

<a>
 <a>
    <b>xxxx</b>
    <c>xxxx</c>
 </a>
 <a>
    <b>yyyy</b>
    <c>yyyy</c>
 </a>
</a>

我想最终:

 <a>
    <b>xxxx</b>
    <c>xxxx</c>
 </a>
 <a>
    <b>yyyy</b>
    <c>yyyy</c>
 </a>

而不是:

 <a>
    <b>xxxx</b>
    <c>xxxx</c>
    <b>yyyy</b>
    <c>yyyy</c>
 </a>

我对XSL转换和搜索语法知之甚少,所以我希望有人可以帮助我。

2 个答案:

答案 0 :(得分:2)

以下样式表将删除其子项都具有相同名称的外部(父)元素:

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="*"/>

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

<!-- exception for parent whose children have all the same name -->
<xsl:template match="*[*][not(*[name()!=name(..)])]">
    <xsl:apply-templates select="@*|node()"/>
</xsl:template>

</xsl:stylesheet>

当以上内容应用于以下测试输入时:

<root>
    <a>
        <a>
            <b>bbb</b>
            <c>ccc</c>
        </a>
        <a>
            <d>
                <d>ddd</d>      
            </d>
            <e>eee</e>
            <f>
                <f>fff</f>  
                <g>ggg</g>  
            </f>
        </a>
    </a>
</root>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <a>
      <b>bbb</b>
      <c>ccc</c>
   </a>
   <a>
      <d>ddd</d>
      <e>eee</e>
      <f>
         <f>fff</f>
         <g>ggg</g>
      </f>
   </a>
</root>

答案 1 :(得分:1)

当孩子的名字与父母的名字相符时,不要删除孩子,而是当你的名字与其所有孩子的名字相同时,你真的想要删除父母

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

<xsl:template match="*[*][not(*[name() != name(..)])]">
  <xsl:apply-templates select="@*|node()" />
</xsl:template>

您可以将第二个匹配表达式读作“具有至少一个子元素的任何元素X,并且也没有任何名称与X不同的子元素。”