我有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转换和搜索语法知之甚少,所以我希望有人可以帮助我。
答案 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不同的子元素。”