来自变量的 XSLT for-each-group 不起作用

Posted

技术标签:

【中文标题】来自变量的 XSLT for-each-group 不起作用【英文标题】:XSLT for-each-group from variable does not work 【发布时间】:2017-09-09 22:44:44 【问题描述】:

XSLT 2.0 中的 for-each-group 在文件中按预期工作,但在变量中没有。

有这个文件: ~$ cat test.xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <delimiter/>
    <c>A</c><c>B</c>
  <delimiter/>
    <c>C</c>
</root>

使用样式表对该文件进行分组:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" version="1.0"
  encoding="UTF-8" indent="yes" omit-xml-declaration="no" />

<xsl:template match="*">

  <!-- variable not used for file test -->
  <xsl:variable name="fields">
    <root>
      <delimiter/>
      <c>A</c><c>B</c>
      <delimiter/>
      <c>C</c>
    </root>
  </xsl:variable>

  <xsl:for-each-group select="*" group-starting-with="delimiter">
    <field>
      <xsl:for-each select="current-group()">
        <xsl:value-of select="self::c"/>
      </xsl:for-each>
    </field>
  </xsl:for-each-group>

</xsl:template>

</xsl:stylesheet>

我得到了我想要的结果:

<?xml version="1.0" encoding="UTF-8"?>
<field>AB</field>
<field>C</field>

尝试将变量 name="fields" 分组为:

<xsl:for-each-group select="$fields/*" group-starting-with="delimiter">

我得到了结果:

<?xml version="1.0" encoding="UTF-8"?>
<field/>

为什么 for-each-group 作用于文件而不作用于变量?

【问题讨论】:

【参考方案1】:

变量fields是一个document-node(),可以定义变量的类型为element()

<xsl:variable name="fields" as="element()">
    <root>
        <delimiter/>
        <c>A</c><c>B</c>
        <delimiter/>
        <c>C</c>
    </root>
</xsl:variable>

【讨论】:

就这么简单。但你必须知道:) 非常感谢。 @Ingo,作为替代方案,您可以将select 中的路径调整为&lt;xsl:for-each-group select="$fields/root/*" group-starting-with="delimiter"&gt; @MartinHonnen 是的,它也可以,谢谢。我一步一步地了解xslt的细节。这意味着选择$fields/* 我将获得一个隐含的文档节点,否则我将获得一个隐含的元素节点?但从现在开始,我将始终指定类型以确保稳定性。对于像我这样对基础知识感兴趣的人,这里是我找到的链接:linklink。但这是否意味着我只能将变量作为元素节点进行查询? 给定您的初始声明&lt;xsl:variable name="fields"&gt;&lt;root&gt;...&lt;/root&gt;&lt;/xsl:variable&gt;,该变量包含一个文档节点,其中包含一个名为root 的根元素,其中包含其他元素。当然,要选择 for-each-group 中的其他元素,您需要路径 $fields/root/*,就像您使用过路径时需要的路径一样,例如&lt;xsl:variable name="fields" select="doc('fields.xml')"/&gt; 加载一个普通的 XML 文档。 &lt;xsl:template match="*"&gt; 匹配任何元素。我建议你从 XSLT 和 XPath 的介绍开始,有一些不错的书籍和课程,例如 pluralsight.com/courses/xslt-foundations-part1

以上是关于来自变量的 XSLT for-each-group 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

XSLT使用for-each-group进行分组并使用填充元素

XSL:IF 内 XSL:for-each-group

XSLT:复杂分组的问题

将 Muenchian 分组应用于 XSLT

如何使用 Apache Camel 在 XSLT 中为每个组申请

XSLT 2.0:根据 for-each -group 的当前索引评估和修改元素值