我正在改变这个XML:
<?xml version='1.0' encoding='utf-8'?>
<song xmlns="http://openlyrics.info/namespace/2009/song" version="0.8" createdIn="OpenLP 2.0.1" modifiedIn="OpenLP 2.0.1" modifiedDate="2012-03-14T02:21:52">
<properties>
<titles>
<title>Amazing Grace</title>
</titles>
<authors>
<author>John Newton</author>
</authors>
</properties>
<lyrics>
<verse name="v1">
<lines>Amazing grace, how sweet the sound<br/>That saved a wretch like me<br/>I once was lost, but now am found<br/>Was blind but now I see</lines>
</verse>
使用此XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:o="http://openlyrics.info/namespace/2009/song">
<xsl:output method="html" />
<xsl:template match="o:song">
<html>
<body>
<h2><xsl:value-of select="o:properties/o:titles/o:title"/><br /></h2>
<h3><xsl:for-each select="o:properties/o:authors/o:author">
<xsl:value-of select="."/><br />
</xsl:for-each></h3>
<xsl:for-each select="o:lyrics/o:verse/o:lines">
<xsl:copy-of select="." />
</xsl:for-each>
</body>
</html>
</xsl:template>
“lines”的每个部分都有一个我想保留的br / tag,这就是我使用copy-of而不是value-of的原因。这就是我想从“线”中得到的:
<lines xmlns="http://openlyrics.info/namespace/2009/song">Amazing grace, how sweet the sound<br/>That saved a wretch like me
相反,XSLT将br / tag更改为
<br></br>
并产生两个换行符,而不仅仅是我想要的换行符。
<lines xmlns="http://openlyrics.info/namespace/2009/song">Amazing grace, how sweet the sound<br></br>
有没有办法阻止这个br /转换并保留XML中存在的br /标记,同时仍然使用copy-of?我在这里做错了什么?
注意:奇怪的是,当我删除“song”标签中的命名空间并将XSLT编写为没有名称空间时,例如
<xsl:for-each select="lyrics/verse/lines">
<xsl:copy-of select="." />
那时我没有这个问题。 br /标签被保留。所以我觉得它与使用命名空间有关。
有什么想法吗?
答案 0 :(得分:3)
问题不在于XSLT,而是将XSLT的结果文档序列化为字符串。
您已在XSLT中指定了“HTML”的输出方法,该方法由序列化程序使用,但并非您输出的所有内容实际上都是HTML。 行不是HTML元素,而且,因为它有一个命名空间,所有子 br 元素当前都是命名空间的一部分,所以这些可能不会被视为HTML元素。
删除命名空间后, br 会被视为HTML元素,并且您会获得预期的行为,因为序列化过程知道如何处理它们。
解决此问题的一种方法是确保在没有命名空间的情况下输出 br 元素。不要使用 xsl:for-each 作为行,而是使用 xsl:apply-templates
<xsl:apply-templates select="o:lyrics/o:verse/o:lines" />
然后你会有匹配行和 br 的模板。特别是,匹配 br 的模板将输出没有命名空间的元素。
试试这个XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:o="http://openlyrics.info/namespace/2009/song" exclude-result-prefixes="o">
<xsl:output method="html"/>
<xsl:template match="o:song">
<html>
<body>
<h2>
<xsl:value-of select="o:properties/o:titles/o:title"/>
<br/>
</h2>
<h3>
<xsl:for-each select="o:properties/o:authors/o:author">
<xsl:value-of select="."/>
<br/>
</xsl:for-each>
</h3>
<xsl:apply-templates select="o:lyrics/o:verse/o:lines"/>
</body>
</html>
</xsl:template>
<xsl:template match="o:lines">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="o:br">
<br/>
</xsl:template>
</xsl:stylesheet>
这应输出以下内容
<html>
<body>
<h2>Amazing Grace<br></h2>
<h3>John Newton<br></h3>
<lines xmlns="http://openlyrics.info/namespace/2009/song">
Amazing grace, how sweet the sound<br xmlns="">
That saved a wretch like me<br xmlns="">
I once was lost, but now am found<br xmlns="">
Was blind but now I see
</lines>
</body>
</html>
在浏览器中查看时,至少应该为您提供一次换行符。