【问题标题】:XSLT Strip All Tabs In Text OutputXSLT 去除文本输出中的所有选项卡
【发布时间】:2014-02-05 20:45:35
【问题描述】:

愚蠢的,简单的问题。当我输出文本时,它仍然会根据我的格式化/缩进 XSL 结构获取选项卡。如何指示转换器忽略样式表中的间距,同时仍保持其格式整齐?

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

      <xsl:template match="/">
        <xsl:apply-templates select="Foo/Bar"></xsl:apply-templates>
      </xsl:template>
      <xsl:template match="Bar">   
<xsl:for-each select="AAA"><xsl:for-each select="BBB"><xsl:value-of select="Label"/>|<xsl:value-of select="Value"/><xsl:text>&#10;</xsl:text></xsl:for-each></xsl:for-each>
</xsl:template>

      </xsl:stylesheet>

逐行生成输出,没有制表符:

SomeLabel|SomeValue
SomeLabel|SomeValue
SomeLabel|SomeValue


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

  <xsl:template match="/">
    <xsl:apply-templates select="Foo/Bar"></xsl:apply-templates>
  </xsl:template>
  <xsl:template match="Bar">   
    <xsl:for-each select="AAA">   
        <xsl:for-each select="BBB">   
            <xsl:value-of select="Label"/>|<xsl:value-of select="Value"/>
             <xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:for-each>

  </xsl:template>

  </xsl:stylesheet>

使用标签生成输出:

SomeLabel|SomeValue
    SomeLabel|SomeValue
    SomeLabel|SomeValue

更新: 添加这个并不能解决它:

<xsl:output method="text" indent="no"/>
  <xsl:strip-space elements="*"></xsl:strip-space> 

这是人为的,但您可以想象 XML 看起来像这样:

<Foo>
  <Bar>
    <AAA>
      <BBB>
        <Label>SomeLabel1</Label>
        <Value>SomeValue1</Value>
      </BBB>
      <BBB>    
        <Label>SomeLabel2</Label>
        <Value>SomeValue2</Value>
      </BBB>
      <BBB>
        <Label>SomeLabel3</Label>
        <Value>SomeValue3</Value>
      </BBB>
    </AAA>
  </Bar>
</Foo>

【问题讨论】:

  • 您发布的 XSLT 代码不会产生您声称的结果:xsltransform.net/pPgCcop
  • @michael.hor257k 已更新。 xsltransform.net 上的缩进是正确的,但我在 Visual Studio 和 notepad++ 中运行了它,并且当 XSLT 缩进时,两者都将制表符插入到输出中。

标签: xslt formatting


【解决方案1】:

您可以尝试将所有当前文本节点包装在 xsl:text 中。例如,试试这个

  <xsl:for-each select="BBB">
    <xsl:value-of select="Label"/>
     <xsl:text>|</xsl:text>
     <xsl:value-of select="Value"/>
     <xsl:text>|</xsl:text>
  </xsl:for-each>

或者,您可以使用 concat 函数。

  <xsl:for-each select="BBB">
    <xsl:value-of select="concat(Label, '|')"/>
    <xsl:value-of select="concat(Value, '|')"/>
  </xsl:for-each>

如果你愿意,你甚至可以将这两个语句合二为一

  <xsl:for-each select="BBB">
    <xsl:value-of select="concat(Label, '|', Value, '|')"/>
  </xsl:for-each>

编辑:如果您不想多次输入分隔符|,您可以使用模板匹配来输出文件。首先,将 value-of 替换为 apply-templates 像这样

    <xsl:for-each select="BBB">   
        <xsl:apply-templates select="Label"/>
        <xsl:apply-templates select="Value"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>

然后你会有一个特定的模板来匹配 Label,你不需要输出分隔符,另一个更通用的模板匹配 BBB 的任何孩子

<xsl:template match="BBB/Label" priority="1">
   <xsl:value-of select="." />
</xsl:template>

<xsl:template match="BBB/*">
   <xsl:text>|</xsl:text><xsl:value-of select="." />
</xsl:template>

(此处需要优先级,以确保Label与第一个模板匹配,而不是通用模板)。当然,在这种情况下,您也不能在 Label 上执行 apply-templates,而只需为该标签执行 xsl:value-of

此外,如果字段按照它们在 XML 中出现的顺序输出,您可以将 for-each 简化为仅此

    <xsl:for-each select="BBB">   
        <xsl:apply-templates />
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>

【讨论】:

  • 这可行,我认为这是部分解决方案。如果我有两个字段,效果很好,但实际上我必须连接大约 50 个字段。有没有一种方法可以在不将 concat 应用于您需要的所有内容的情况下普遍解决这个问题?
  • 另外,这仍然在每个标签之前包含一个标签。
  • @kakridge "实际上我必须连接大约 50 个字段。" 我们只能按照您向我们展示的内容进行。在您的代码中,您明确地调用每个“字段”,因此向每个此类调用添加一个文本元素并不费力。或者,您可以构造一个 for-each“字段”循环并将文本元素插入其中一次。
  • 当然,这不是很大的努力,但我很懒,更喜欢忽略整个样式表中元素之外的所有空格的方法。我听说这是不可能的。
  • 谢谢各位,xsl:text 元素是一个可以接受的答案。仍然感到失望的是,无法使用处理指令忽略样式表中的所有空格。也许 strip-space 应该这样做,但它不适用于我正在使用的处理工具。
猜你喜欢
  • 1970-01-01
  • 2019-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多