以下是在不同嵌套级别上包含关键元素sr
和ds
的XML文档:
<doc>
<p>
<sr>some text 1</sr>
<ds>some text 2</ds>
</p>
<p>
<span>
<sr>some text 3</sr>
<ds>some text 4</ds>
</span>
<span>
<sr><b>some</b> text 5</sr>
<ds>some text <sup>6</sup></ds>
</span>
</p>
<td colspan="2">
<sr><b>some</b> text 7</sr>
<ds>some text <b>8</b></ds>
</td>
</doc>
任务是按原样输出HTML,但遇到<sr>
和<ds>
元素时,请对父元素执行一些修改:
sr
的内容放入父元素的title
属性中,删除所有嵌套标记;只保留纯文本ds
元素的内容原样放入父元素的主体,并使用所有嵌套标记例如,上述文档应如下所示:
<body>
<p title="some text 1">some text 2</p>
<p>
<span title="some text 3">some text 4</span>
<span title="some text 5">some text <sup>6</sup></span>
</p>
<td colspan="2" title="some text 7">some text <b>8</b></td>
</body>
这可以用XSLT吗?
目前我只知道如何在固定的嵌套级别(如<xsl:for-each select="/level1/level2">
)上处理XML元素,或者如何选择不同级别的元素但只选择它们,而我的任务是按原样输出其余的元素。
你能给出一个线索吗?
有时我认为将文档完全读入字符串并在没有XSLT的情况下进行一系列普通字符串替换会更简单。
答案 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>
<xsl:template match="/doc">
<body>
<xsl:apply-templates/>
</body>
</xsl:template>
<xsl:template match="sr">
<xsl:attribute name="title">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match="ds">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
请注意,这假设sr
始终位于ds
或任何其他同级元素之前。
答案 1 :(得分:0)
以下解决方案无论sr
和ds
元素的顺序如何都有效:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()[not(self::ds )]|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[sr and ds]" priority="8">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="title"><xsl:value-of select="sr"/></xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*" priority="9">
<body>
<xsl:apply-templates/>
</body>
</xsl:template>
<xsl:template match="sr" priority="10"/>
</xsl:stylesheet>
应用于提供的XML文档的此变体(请注意sr
和ds
的任意顺序):
<doc>
<p>
<ds>some text 2</ds>
<sr>some text 1</sr>
</p>
<p>
<span>
<sr>some text 3</sr>
<ds>some text 4</ds>
</span>
<span>
<sr><b>some</b> text 5</sr>
<ds>some text <sup>6</sup></ds>
</span>
</p>
<td colspan="2">
<ds>some text <b>8</b></ds>
<sr><b>some</b> text 7</sr>
</td>
</doc>
产生了想要的正确结果:
<body>
<p title="some text 1">some text 2</p>
<p>
<span title="some text 3">some text 4</span>
<span title="some text 5">some text <sup>6</sup>
</span>
</p>
<td colspan="2" title="some text 7">some text <b>8</b>
</td>
</body>