我正在使用 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> </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>
包含三个文本节点:
-
"\n··"
(在<xml>
之后) -
"·value·"
- "
\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/