我使用XML来存储一个小的联系人列表,并尝试编写一个XSL模板,将其转换为CSV文件.我遇到的问题是输出中有空格.
输出:
Friend, John, Smith, Home,
123 test,
Sebastopol,
California,
12345,
Home 1-800-123-4567, Personal john.smith@gmail.com
Run Code Online (Sandbox Code Playgroud)
我缩进/间隔了源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>
Run Code Online (Sandbox Code Playgroud)
这是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>
Run Code Online (Sandbox Code Playgroud)
Tom*_*lak 94
在XSLT中,默认情况下会保留空白区域,因为它很可能是相关数据.
防止输出中不需要的空白区域的最佳方法不是首先创建它.不要这样做:
<xsl:template match="foo">
foo
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
因为那是"\n··foo\n"从处理器的角度来看的.相反
<xsl:template match="foo">
<xsl:text>foo</xsl:text>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
只要在XML元素之间出现,样式表中的空格就会被忽略.简单地说:永远不要在XSLT代码中的任何地方使用"裸"文本,始终将其包含在元素中.
另外,使用非特定的:
<xsl:apply-templates />
Run Code Online (Sandbox Code Playgroud)
是有问题的,因为文本节点的默认XSLT规则说"将它们复制到输出".这也适用于"仅限空白"的节点.例如:
<xml>
<data> value </data>
</xml>
Run Code Online (Sandbox Code Playgroud)
包含三个文本节点:
"\n··"(紧接着<xml>)"·value·"\n"(就在之前</xml>)为了避免#1和#3潜入输出(这是不需要的空格的最常见原因),您可以通过声明一个空模板来覆盖文本节点的默认规则:
<xsl:template match="text()" />
Run Code Online (Sandbox Code Playgroud)
现在,所有文本节点都已静音,并且必须显式创建文本输出:
<xsl:value-of select="data" />
Run Code Online (Sandbox Code Playgroud)
要从值中删除空格,可以使用normalize-space()XSLT函数:
<xsl:value-of select="normalize-space(data)" />
Run Code Online (Sandbox Code Playgroud)
但要小心,因为函数规范化了字符串中的任何空格,例如"·value··1·"会变成"value·1".
另外你可以使用<xsl:strip-space>和<xsl:preserve-space>元素,虽然通常这不是必需的(而且就个人而言,我更喜欢如上所示的显式空白处理).
默认情况下,XSLT模板已<xsl:preserve-space>设置,这将在输出中保留空格.您可以添加<xsl:strip-space elements="*">以告诉它删除空格的位置.
您可能还需要包含normalize-space指令,如下所示:
<xsl:template match="text()"><xsl:value-of select="normalize-space(.)"/></xsl:template>
Run Code Online (Sandbox Code Playgroud)
以下是W3学校保存/剥离空间的示例.
| 归档时间: |
|
| 查看次数: |
61870 次 |
| 最近记录: |