我在xslt中有以下问题。给定示例xml:
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>A</cd>
<dvd id='A'>B</dvd>
<dvd id='B'>C</dvd>
</catalog>
我想输出标签cd
为CD
, dvd[@id="B"]
为CD
,所有其他dvd
为DVD
。使用三个模板(cd、dvd和dvd, id=B)的简单转换工作得很好,但是产生的结果如下:
<CD>A</CD>
<DVD>B</DVD>
<CD>C</CD>
问题是验证模式期望DVD
s遵循CD
s,因此CD->DVD->CD是错误的。我想出了这个模式来解决这个问题:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="catalog">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="cd">
<CD>
<xsl:value-of select="."/>
</CD>
<xsl:if test="../dvd[@id='B']">
<xsl:apply-templates select="../dvd[@id='B']" mode="keep"/>
</xsl:if>
</xsl:template>
<xsl:template match="dvd">
<DVD>
<xsl:value-of select="."/>
</DVD>
</xsl:template>
<xsl:template match="dvd[@id='B']" mode="keep">
<CD>
<xsl:value-of select="."/>
</CD>
</xsl:template>
<xsl:template match="dvd[@id='B']">
<!-- do nothing -->
</xsl:template>
</xsl:stylesheet>
它完成了工作,但似乎有点冗长和复杂——我正在检查一个节点是否存在,转换它,当它出现在正常的处理流中时,我忽略它——我甚至不确定它是否完全正确。
你能建议一种方法,其中dvd[@id="B"]
将只有一个模板,将<CD>
输出在路径下,如"在此级别的最后一张cd之后"?
如何:
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:template match="catalog">
<xsl:apply-templates select="cd | dvd[@id='B']"/>
<xsl:apply-templates select="dvd[not(@id='B')]"/>
</xsl:template>
<xsl:template match="cd">
<CD>
<xsl:value-of select="."/>
</CD>
</xsl:template>
<xsl:template match="dvd">
<DVD>
<xsl:value-of select="."/>
</DVD>
</xsl:template>
<xsl:template match="dvd[@id='B']">
<CD>
<xsl:value-of select="."/>
</CD>
</xsl:template>
</xsl:stylesheet>
或者,如果你愿意:
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:template match="catalog">
<xsl:apply-templates select="cd | dvd[@id='B']"/>
<xsl:apply-templates select="dvd[not(@id='B')]"/>
</xsl:template>
<xsl:template match="cd | dvd[@id='B']">
<CD>
<xsl:value-of select="."/>
</CD>
</xsl:template>
<xsl:template match="dvd">
<DVD>
<xsl:value-of select="."/>
</DVD>
</xsl:template>
</xsl:stylesheet>
注意,结果不是格式良好的XML,因为它没有单个根元素。