【发布时间】:2012-11-30 11:10:18
【问题描述】:
示例 xml 是:
<a amp="a"><b><c>this is the text</c></b></a>
需要转化为:
<a amp="a"><c>this is the text</c></a>
【问题讨论】:
示例 xml 是:
<a amp="a"><b><c>this is the text</c></b></a>
需要转化为:
<a amp="a"><c>this is the text</c></a>
【问题讨论】:
解决方案 #1: 对 smaccoun 的解决方案进行了轻微改进,该解决方案将保留 c 元素上的任何属性(例如 XML 不是必需的):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="c">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
解决方案 #2 另一种利用 built-in template rules 的替代方案,它为所有元素应用模板并复制所有 text():
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--identity template for the c element, it's decendant nodes,
and attributes (which will only get applied from c or
descendant elements)-->
<xsl:template match="@*|c//node()|c">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
解决方案 #3: 修改后的 identity transform:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--identity template, copies all content by default-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--don't generate content for these matched elements,
just apply-templates to it's children-->
<xsl:template match="a|b">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
解决方案#4如果您知道自己想要什么,只需从根节点上的匹配项中复制它
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:copy-of select="a/b/c" />
</xsl:template>
</xsl:stylesheet>
如果您只想从输入中删除 <b> 元素,则应将修改后的身份转换与匹配 <b> 元素的模板一起使用,该模板仅将模板应用于其子元素。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!--identity template, copies all content by default-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!--don't generate content for the <b>, just apply-templates to it's children-->
<xsl:template match="b">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
【讨论】:
a,以便由@*|node() 上的通用匹配处理,这将复制内容。 b 上的匹配将抑制其内容,但将模板应用于其子级,这也将匹配复制到输出的通用模板。
在<c> 上应用模板,然后只使用复制设计模式。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match='c'>
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
【讨论】:
<c> 具有属性,则这些值将被复制为文本内容,而不是被保留。 (例如<c amp="foo">this is the text</c> 将导致<c>foothis is the text</c>)