【问题标题】:XSLT 1.0 adds extra spaces in between the stringsXSLT 1.0 在字符串之间添加了额外的空格
【发布时间】:2018-06-29 03:40:14
【问题描述】:

我有一个 XSLT 转换,我从中提取客户名称详细信息。我正在使用 XSLT 1.0。转换似乎在字符串之间插入了额外的空格。以下示例和详细信息:

XML:

<Root>
   <Customer>
      <PrimaryGuest>
       <FirstName>Jonathan (Jonny)</FirstName>
       <LastName>Doe</LastName> 
       <MiddleName>Lewis</MiddleName>
     </PrimaryGuest>
     <PrimaryGuest>
       <FirstName>Mary</FirstName>
       <LastName>Doe</LastName> 
       <MiddleName>L</MiddleName>
     </PrimaryGuest>
  </Customer>
</Root>

XSLT:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:exslt="http://exslt.org/common"
xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl xsl xsd exslt"
version="1.0">

<xsl:output omit-xml-declaration="yes" />
<xsl:variable name="TravelerName">
 <xsl:choose>
    <xsl:when test="$LOB = 11">
        <xsl:for-each select="Root/Customer/PrimaryGuest | Root/PriorCustomer/PrimaryGuest">
         <xsl:if test="(position() = '1')">[</xsl:if>
            <xsl:variable name="FirstName">
                <xsl:value-of select="FirstName" />
            </xsl:variable>
            <xsl:variable name="LastName">
                <xsl:value-of select="LastName" />
            </xsl:variable>
            <xsl:variable name="MiddleName">
                <xsl:value-of select="MiddleName" />
            </xsl:variable>
            <xsl:variable name="SuffixName">
                <xsl:value-of select="SuffixName" />
            </xsl:variable>
            <xsl:variable name="TravelerName">
                <xsl:value-of
                        select="concat('[&quot;',$FirstName, '&quot;, ', '&quot;', $LastName, '&quot;, ', '&quot;', $MiddleName, '&quot;, ', '&quot;', $SuffixName, '&quot;]')" />
            </xsl:variable>
            <xsl:value-of select="$TravelerName" />
                <xsl:if test="not(position() = last())">, </xsl:if>
                <xsl:if test="(position() = last())">]</xsl:if>
        </xsl:for-each>
    </xsl:when>
    <xsl:otherwise>
        <xsl:text></xsl:text>
    </xsl:otherwise>
</xsl:choose>
</xsl:variable>

输出:

TravelerName:[[["Jonathan       (Jonny)", "Doe", "Lewis", ""], ["Mary", "Doe", "L", ""] ]]

我尝试了几种不同的方法。如果我看到前导或尾随空格但看不到中间的空格,这对我来说很有意义。任何帮助将不胜感激。

【问题讨论】:

  • 您使用的是什么 XSLT 处理器?
  • 在我尝试使用“JRE 实例默认值”和“Xalan 2.7.1”的本地 Eclipse 中无法重现。我不确定我的部署环境中有什么。我的战争中没有添加任何处理器。
  • 要找出您正在使用的处理器,请将&lt;xsl:comment select="system-property('xsl:vendor')"/&gt; 添加到您的样式表中。
  • 我试过 。当我在 Eclipse 中对样式表运行单元测试时,它不会打印任何内容。

标签: xml xslt xml-parsing xslt-1.0


【解决方案1】:

最短的答案

也许您的 source XML 包含例如Tab 字符或额外的空格 (例如在 FirstName 中)? 要使脚本抵抗这种情况,请使用normalize-space 函数。

现在是更长的版本

我检查了您的原始源 XML 并稍作修改 您的 XSLT 脚本,使用版本 1.0Xalan 处理器, 看到http://xsltransform.net/6q1R79r,输出就OK了。

请注意,我将 for-each 中的 select 更改为 Root/*/PrimaryGuest

原因是在 XSLT 1.0|(联合运算符)在select 中没有 工作(虽然它在match 表达式中工作)。 要在“我的”示例中验证这一点,请将 | x 添加到 select 属性 (在for-each),输出会更短。

如果您想将select 范围限制为CustomerPriorCustomer, 在* 之后添加谓词:[name()='Customer' or name()='PriorCustomer']

另说:

在您的代码中,我看到了一个奇怪的做法: 您创建一个变量(例如FirstName),其中包含一个名称相同的元素, 并且此变量的唯一目的是在value-of(在本例中为$FirstName)输出其值。

我认为只使用元素名称要简单得多,无需创建 任何临时变量,就像我在脚本中所做的那样。

另请注意,可以输出初始 [ 和尾随 ] 分别在for-each 循环之前和之后。 此更改使脚本更有效且更易于阅读。

【讨论】:

  • 感谢您的建议。这非常有用!我要试试这个。如果它有效,我会在几天/几周内更新。