使用html标记规范化空间问题

时间:2014-08-27 14:37:36

标签: html xml xslt xslt-1.0

这是一个适合你的XSLT大师: - )

我必须处理来自我无法控制的Java程序的XML输出。

在此应用输出的文档中,html标记仍为

<u><i><b><em>  

等,而不是

&lt;u&gt;&lt;i&gt;&lt;b&gt;&lt;em&gt; and so on.

这不是一个大问题,我使用XSLT来修复它,但使用normalize-space去除多余的空格也会删除这些html标记之前的空格。

实施例

<Locator Precode="7">
<Text LanguageId="7">The next word is <b>bold</b> and is correctly spaced 
around the html tag,
but the sentence has extra whitespace and 
line breaks</Text>
</Locator>

如果我运行XSLT脚本,我们用来删除额外的空白区域,这是相关部分

<xsl:template match="text(.)">
<xsl:value-of select="normalize-space()"/>
</xsl:template>

在结果输出中,xslt已正确删除了额外的空格和换行符,但它也删除了导致此输出的标记之前的空格: -

The next word isboldand is correctly spaced around the html tag, but the sentence has extra whitespace and line breaks.

“粗体”一词之前和之后的间距也已被删除。

任何人都有任何想法如何防止这种情况发生?非常好,我的智慧结束,所以任何帮助将不胜感激!

: - )

你好,

是的,当然,这是完整的样式表。我们必须在一遍中处理html标签和间距

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="UTF-8"/>
<xsl:strip-space elements="*" />  


<xsl:template match="@*|node()">
 <xsl:copy> 
  <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
</xsl:template>


<xsl:template match="Text//*">
  <xsl:value-of select="concat('&lt;',name(),'&gt;')" />
  <xsl:apply-templates />
  <xsl:value-of select="concat('&lt;/',name(),'&gt;')" />
</xsl:template>
<xsl:template match="text()">
    <xsl:value-of select="normalize-space(.)"/>
</xsl:template>


<xsl:template match="Instruction//*">
  <xsl:value-of select="concat('&lt;',name(),'&gt;')" />
  <xsl:apply-templates />
  <xsl:value-of select="concat('&lt;/',name(),'&gt;')" />
</xsl:template>

<xsl:template match="Title//*">
  <xsl:value-of select="concat('&lt;',name(),'&gt;')" />
  <xsl:apply-templates />
  <xsl:value-of select="concat('&lt;/',name(),'&gt;')" />
</xsl:template>


</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

XSLT 1.0解决方案是一个XPath表达式,用一个空格字符替换一个空格字符序列。这个想法是我自己的,它来自an answer by Dimitre Novatchev

内置normalize-space()函数的优势在于保留尾随空格(在您的情况下,在b元素之前和之后)。

编辑:作为对您编辑问题的回复。下面是包含在样式表中的所述XPath表达式。也:

  • 明确地说omit-xml-declaration="no"是多余的。这是XSLT处理器采取的默认操作
  • 您的一些模板具有相同的内容。我使用|将它们汇总为一个。

<强>样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="UTF-8"/>
<xsl:strip-space elements="*" />  


<xsl:template match="@*|node()">
 <xsl:copy> 
  <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
</xsl:template>


<xsl:template match="Text//*|Instruction//*|Title//*">
  <xsl:value-of select="concat('&lt;',name(),'&gt;')" />
  <xsl:apply-templates />
  <xsl:value-of select="concat('&lt;/',name(),'&gt;')" />
</xsl:template>

<xsl:template match="text()">
  <xsl:value-of select=
  "concat(substring(' ', 1 + not(substring(.,1,1)=' ')),
          normalize-space(),
          substring(' ', 1 + not(substring(., string-length(.)) = ' '))
          )
  "/>
  </xsl:template>

</xsl:stylesheet>

XML输出

<?xml version="1.0" encoding="UTF-8"?>
<Locator Precode="7">
   <Text LanguageId="7">The next word is &lt;b&gt;bold&lt;/b&gt; and is correctly spaced around the html tag, but the sentence has extra whitespace and line breaks</Text>
</Locator>