将XML转换为纯文本 - 我应该如何忽略/处理XSLT中的空格?

Pot*_*eer 36 xml xslt whitespace dokuwiki

我正在尝试使用XSLT将XML文件转换为dokuwiki使用的标记.这实际上在某种程度上起作用,但XSL文件中的缩进被插入到结果中.目前,我有两个选择:完全放弃这个XSLT,找到另一种从XML转换为dokuwiki标记的方法,或者从XSL文件中删除大约95%的空白,使其难以理解并成为维护的噩梦.

有没有办法在XSL文件中保留缩进而不将所有空格传递给最终文档?

背景:我正在将autodoc工具从静态HTML页面迁移到dokuwiki,因此,只要应用程序团队遇到编写不当的代码,应用程序团队就可以进一步记录服务器团队开发的API.逻辑是为autodoc工具留出每个页面的一部分,并允许在该块之外的任何地方进行注释.我正在使用XSLT,因为我们已经有了从XML转换为XHTML的XSL文件,而且我认为重写XSL比从头开始编写自己的解决方案要快.

编辑:啊,对,愚蠢的我,我忽略了缩进属性.(其他背景说明:我是XSLT的新手.)另一方面,我仍然需要处理新行.Dokuwiki使用管道来区分表列,这意味着表行中的所有数据必须在一行上.有没有办法抑制输出的换行(只是偶尔),所以我可以在一个有点可读的区域为每个表格单元做一些相当复杂的逻辑?

Jen*_*niT 77

在XSLT转换的结果中获得不需要的空格有三个原因:

  1. 来自源文档中节点之间的空白
  2. 来自源文档中节点内的空白
  3. 来自样式表的空白

我将谈论所有三个,因为很难说出空白来自哪里,所以你可能需要使用几种策略.

要解决源文档中节点之间的空白,您应该使用<xsl:strip-space>去除两个节点之间出现的任何空白,然后使用它<xsl:preserve-space>来保留可能出现在混合内容中的重要空白.例如,如果您的源文档如下所示:

<ul>
  <li>This is an <strong>important</strong> <em>point</em></li>
</ul>
Run Code Online (Sandbox Code Playgroud)

那么你将要忽略的空白<ul><li>之间的</li></ul>,这是不显著,但保留之间的空白<strong><em>元素,这显著(否则你会得到"这是一个重要的*****点*").要做到这一点

<xsl:strip-space elements="*" />
<xsl:preserve-space elements="li" />
Run Code Online (Sandbox Code Playgroud)

elements上属性<xsl:preserve-space>应该基本上列出您的所有文件中有混合内容的元素.

另外:使用<xsl:strip-space>也会减少内存中源代码树的大小,并使样式表更有效,所以即使你没有这种空白问题也值得去做.

要解决源文档中节点内出现的空白,您应该使用normalize-space().例如,如果您有:

<dt>
  a definition
</dt>
Run Code Online (Sandbox Code Playgroud)

并且您可以确定该<dt>元素不会包含您想要执行某些操作的任何元素,然后您可以执行以下操作:

<xsl:template match="dt">
  ...
  <xsl:value-of select="normalize-space(.)" />
  ...
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

前导和尾随空格将从<dt>元素的值中删除,您将获得字符串"a definition".

要解决来自样式表的空格,也就是您遇到的那个空格,就是当您在模板中包含文本时,如下所示:

<xsl:template match="name">
  Name:
  <xsl:value-of select="." />
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

XSLT样式表的解析方式与它们处理的源文档的解析方式相同,因此上述XSLT被解释为一个树,它包含一个<xsl:template>元素,该元素match的第一个子节点是文本节点,第二个子节点是<xsl:value-of>具有select属性的元素.文本节点具有前导和尾随空格(包括换行符); 因为它是样式表中的文字文本,所以它会被字面上复制到结果中,包含所有前导和尾随空格.

但是XSLT样式表中的一些空格会被自动剥离,即节点之间的空格.因为有之间换行,你没有得到你的结果换行符<xsl:value-of>和的结束<xsl:template>.

要仅获得结果中所需的文本,请使用以下<xsl:text>元素:

<xsl:template match="name">
  <xsl:text>Name: </xsl:text>
  <xsl:value-of select="." />
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

XSLT处理器将忽略节点之间出现的换行符和缩进,并仅输出<xsl:text>元素中的文本.