xml - XSLT - 从模板中删除空格

标签 xml xslt

我正在使用 XML 来存储一个小的联系人列表,并尝试编写一个 XSL 模板,将其转换为 CSV 文件。我遇到的问题是输出中有空格。

输出:

Friend, John, Smith, Home,
        123 test,
       Sebastopol,
       California,
       12345,
     Home 1-800-123-4567, Personal john.smith@gmail.com

我已经缩进/间隔了源 XML 文件和关联的 XSL 模板,以使其更易于阅读和开发,但所有额外的空白都会进入输出。 XML 本身在节点内部没有额外的空白,只是在节点外部用于格式化,XSLT 也是如此。

为了使 CSV 文件有效,每个条目都需要独占一行,而不是分开。除了从 XML 和 XSLT 中去除所有额外的空白(使它们只是一长串代码)之外,还有其他方法可以去除输出中的空白吗?

编辑: 这是一个小的 XML 示例:

<PHONEBOOK>
    <LISTING>
        <FIRST>John</FIRST>
        <LAST>Smith</LAST>
        <ADDRESS TYPE="Home">
            <STREET>123 test</STREET>
            <CITY>Sebastopol</CITY>
            <STATE>California</STATE>
            <ZIP>12345</ZIP>
        </ADDRESS>
        <PHONE>1-800-123-4567</PHONE>
        <EMAIL>john.smith@gmail.com</EMAIL>
        <RELATION>Friend</RELATION>
    </LISTING>
</PHONEBOOK>

这是 XSLT:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />

 <xsl:template match="/">
   <xsl:for-each select="//LISTING">
    <xsl:value-of select="RELATION" /><xsl:text>, </xsl:text>
    <xsl:value-of select="FIRST" /><xsl:text>, </xsl:text>
    <xsl:value-of select="LAST" /><xsl:text>, </xsl:text>

    <xsl:if test="ADDRESS">
     <xsl:for-each select="ADDRESS">
       <xsl:choose>
        <xsl:when test="@TYPE">
         <xsl:value-of select="@TYPE" />,
        </xsl:when>
            <xsl:otherwise>
            <xsl:text>Home </xsl:text>
            </xsl:otherwise>
       </xsl:choose>
       <xsl:value-of select="STREET" />,
       <xsl:value-of select="CITY" />,
       <xsl:value-of select="STATE" />,
       <xsl:value-of select="ZIP" />,
     </xsl:for-each>
    </xsl:if>

    <xsl:for-each select="PHONE">
      <xsl:choose>
       <xsl:when test="@TYPE">
        <xsl:value-of select="@TYPE" />  
       </xsl:when>
       <xsl:otherwise><xsl:text>Home </xsl:text></xsl:otherwise>
      </xsl:choose>
     <xsl:value-of select="."  /><xsl:text  >, </xsl:text>
    </xsl:for-each>

    <xsl:if test="EMAIL">
     <xsl:for-each select="EMAIL">
      <xsl:choose>
       <xsl:when test="@TYPE">
        <xsl:value-of select="@TYPE" /><xsl:text  > </xsl:text> 
       </xsl:when>
       <xsl:otherwise><xsl:text  >Personal </xsl:text></xsl:otherwise>
      </xsl:choose>
      <xsl:value-of select="."  /><xsl:text  >, </xsl:text>
     </xsl:for-each>
    </xsl:if>
    <xsl:text>&#10;&#13;</xsl:text>
   </xsl:for-each>
 </xsl:template>

</xsl:stylesheet>

最佳答案

在 XSLT 中,默认保留空白,因为它很可能是相关数据。

防止输出中出现不需要的空白的最佳方法是一开始就不要创建它。不要这样做:

<xsl:template match="foo">
  foo
</xsl:template>

因为那是 "\n··foo\n" ,从处理器的角度来看。宁愿做

<xsl:template match="foo">
  <xsl:text>foo</xsl:text>
</xsl:template>

样式表中的空白只要出现在 XML 元素之间就会被忽略。简而言之:永远不要在 XSLT 代码中的任何地方使用“裸”文本,始终将其包含在一个元素中。

此外,使用非特定的:

<xsl:apply-templates />

是有问题的,因为文本节点的默认 XSLT 规则说“将它们复制到输出”。这也适用于“仅空白”节点。例如:

<xml>
  <data> value </data>
</xml>

包含三个文本节点:

  1. "\n··" (在 <xml> 之后)
  2. "·value·"
  3. "\n" (就在 </xml> 之前)

为避免 #1 和 #3 潜入输出(这是不需要空格的最常见原因),您可以通过声明一个空模板来覆盖文本节点的默认规则:

<xsl:template match="text()" />

所有文本节点现在都已静音,必须显式创建文本输出:

<xsl:value-of select="data" />

要从值中删除空格,您可以使用 normalize-space() XSLT 函数:

<xsl:value-of select="normalize-space(data)" />

但是要小心,因为该函数规范化了字符串中的任何空白,例如"·value··1·"会变成"value·1" .

此外,您还可以使用 <xsl:strip-space><xsl:preserve-space>元素,尽管通常这不是必需的(而且我个人更喜欢如上所述的显式空白处理)。

关于xml - XSLT - 从模板中删除空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1468984/

相关文章:

xml - xslt is/when is choose 比 if 更有效

XSLT::结果文档

c# - 将 XML 属性读入列表

java - 将 XML 文本节点替换为元素节点

svg - 通过 XSLT 将 SVG 文件上各种路径的填充不透明度设置为 0

xml - 撒克逊语中的 xslt:message - 消息在哪里?

xslt - 子字符串上的 XSL Muenchian 方法

java - 当 ScrollView 不工作时,如何使以下 Android Activity 可滚动?

xml - 已发送消息的 eJabberd 副本

asp.net - 在 IIS 中托管 Sageframe 网站时配置文件错误