【问题标题】:Simple XSLT transformation简单的 XSLT 转换
【发布时间】:2018-03-12 07:40:44
【问题描述】:

我有以下输入文件:

<!-- input.xml --> 
<?xml version="1.0" encoding="UTF-8"?>
<input>
  <value>
    aaa
    <value>
      bbb
      <value>ccc</value>
    </value>
  </value>
</input>

预期输出:

<!-- output.xml --> 
<?xml version="1.0" encoding="UTF-8"?>
<ul>
  <li>aaa</li>
  <li>bbb</li>
  <li>ccc</li>
</ul>

XSLT 文件应该是什么样子?我尝试了以下方法:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/input">
    <ul>
      <xsl:for-each select="//value">
        <li> <xsl:value-of select="."/></li>
      </xsl:for-each>
    </ul> 
  </xsl:template>
</xsl:stylesheet>

但第一个结果 (aaa) 还包含来自其子树 (bbb, ccc) 的值。

【问题讨论】:

  • 最好说明转换应如何处理与您的示例不同的输入文档。比如有两个兄弟值元素怎么办?
  • 你是对的,但这不是一个真实的用例,我只是想了解 XSLT 是如何工作的,所以这只是一个我无法弄清楚的例子。

标签: xml xslt xpath


【解决方案1】:

在您的案例中成功的关键是模板匹配 value 应该只复制当前级别中的文本:

<xsl:value-of select="text()"/>

其实最好加上normalize-space()去掉“additional” 空白字符:

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

打印出当前关卡对应的内容后li 元素,你应该只为子节点放置 apply-templates

<xsl:apply-templates select="*"/>

所以整个脚本如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="input">
    <ul>
      <xsl:apply-templates/>
    </ul>
  </xsl:template>

  <xsl:template match="value">
    <li>
      <xsl:value-of select="normalize-space(text())"/>
    </li>
    <xsl:apply-templates select="*"/>
  </xsl:template>
</xsl:transform>

有关工作示例,请参阅http://xsltransform.net/pNvs5w2

【讨论】:

    【解决方案2】:

    尝试select="text()" 而不是select="." 只选择文本内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-14
      • 2021-12-13
      • 1970-01-01
      • 2023-04-07
      • 2017-06-12
      • 2011-01-08
      相关资源
      最近更新 更多