我是XML / XSL / XSLT的新手,虽然我过去一小时一直在挖掘msdn,3schools.com和google,但我无法想象这一点。我认为是因为CDATA没有被xml解析,但我认为当我的编辑在节点上工作时我应该能够解决这个问题......
请注意,这不是一个非常重要的问题,我只想学习更多的XSL,以及修复那些似乎无法正常工作的东西。
所以...我的脚本在XML文件中保存选项,在这个文件中我还会保存一些可能包含需要转义的字符的代码片段。一个小例子是:
<Snippet title="Version Test">
<![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "& Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode
]]>
</Snippet>
使用以下xsl我得到一个相当不错的缩进:
<!-- Extracted from: http://www.dpawson.co.uk/xsl/sect2/pretty.html (v2) -->
<!-- Cdata info: http://www.altova.com/forum/default.aspx?g=posts&t=1000002342 -->
<!-- Modified By RaptorX -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
indent="yes"
encoding="UTF-8"
cdata-section-elements="Snippet"/>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="comment()|processing-instruction()">
<xsl:copy />
</xsl:template>
</xsl:stylesheet>
<!-- I have to keep the indentation here in this file as
i want it to be on the XML file -->
嗯,基本上它不匹配CDATA部分,所以谷歌搜索我发现我可以做以下有助于一点但产生这个输出:
xsl:copy-of select="@*|node()" /> << -- by adding that i match cdata nodes too
Output:
<Snippet title="Version Test">
<![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode
]]></Snippet> <<-- here is the problem I cant seem to put a newline there lol
所以问题是:
我如何告诉xsl缩进CDATA部分,就像它对其他所有部分一样:
<root>
<child/>
</root>
<Snippet title="Version Test">
<![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode
]]> << --- this is what im looking for
</Snippet>
答案 0 :(得分:2)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"
cdata-section-elements="Snippet"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Snippet/text()">
<xsl:call-template name="replace"/>
<xsl:text>
</xsl:text>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="pText" select="."/>
<xsl:if test="string-length($pText) >0">
<xsl:choose>
<xsl:when test="not(contains($pText,'
'))">
<xsl:value-of select="$pText"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select=
"substring-before($pText, '
')"/>
<xsl:text>
		</xsl:text>
<xsl:call-template name="replace">
<xsl:with-param name="pText"
select="substring-after($pText, '
')"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<Snippet title="Version Test">
<![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "& Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode]]>
</Snippet>
生成想要的正确结果:
<Snippet title="Version Test"><![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "& Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode
]]></Snippet>
<强>解释强>:
身份规则“按原样”复制每个节点。
cdata-section-elements="Snippet"
的{{1}}属性指示XSLT处理器将任何<xsl:output>
元素的任何文本节点序列化为CDATA部分。
当匹配作为Snippet
元素的子节点的文本节点时,有一个模板会覆盖标识模板。
任何此类文本节点的处理都是通过调用Snippet
模板完成的,该模板用NL替换任何NL字符,后跟两个制表符。完成这些替换后,将输出最后一个NL字符,以便结束标记replace
将在新行上。
答案 1 :(得分:0)
这是kludgy但它应该工作,并且超级快。只需使用<xsl:text>
:
<xsl:copy />
<xsl:text>
</xsl:text>