修复 CDATA 部分的缩进
我对 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>
Im completely new to XML/XSL/XSLT, and while i have been digging msdn, 3schools.com and google for the past hour i cant figure this one out. I think is because CDATA isnt parsed by xml, but I thought that as my edit did work on the node i should be able to fix this...
Note that this is not a very important issue, I just want to learn a little bit more of XSL and what better way than fixing stuff that doesnt seem to work as i want it to.
So... my script saves options on an XML file in which i will also save some code snippets which might contain characters that need to be escaped. A small example would be:
<Snippet title="Version Test">
<![CDATA[
version := "AHK Version: " a_ahkversion
unicode := "& Supports Unicode: " (a_isunicode ? "Yes" : "No")
Msgbox % version "`n" unicode
]]>
</Snippet>
With the following xsl i get a fairly good indentation:
<!-- 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 -->
Well, basically it doesnt match CDATA sections, so googling around I found that i could do the following which helps a little but produces this output:
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
So the question is:
how do i tell xsl to indent the CDATA section as it does with everything else:
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
此转换:
应用于提供的 XML 文档时:
产生所需的正确结果:
说明:
身份规则“按原样”复制每个节点。
的cdata-section-elements="Snippet"
属性指示 XSLT 处理器序列化任何Snippet 的任何文本节点
元素作为 CDATA 节。有一个模板可以覆盖身份模板 - 当匹配作为
Snippet
元素子级的文本节点时。任何此类文本节点的处理都是通过调用
replace
模板来完成的,该模板将任何 NL 字符替换为 NL 后跟两个制表符。完成这些替换后,将输出最后一个 NL 字符,以便结束标记将位于新行上。
This transformation:
when applied on the provided XML document:
produces the wanted, correct result:
Explanation:
The identity rule copies every node "as-is".
The
cdata-section-elements="Snippet"
attribute of<xsl:output>
instructs the XSLT processor to serialize any text node of anySnippet
element as a CDATA section.There is a single template that overrides the identity template -- when matching a text node that is a child of a
Snippet
element.The processing of any such text-node is done by calling the
replace
template, which replaces any NL character with NL followed by two tab characters. When these replacements are done, one last NL character is output, so that the end tag</Snippet>
will be on a new line.这有点笨拙,但它应该可以工作并且速度超级快。只需使用
:This is kludgy but it should work and is super quick. Simply use
<xsl:text>
: