从 XSLT 1.0 到 2.0 的转换不会给出标签的第一个文本

Conversion from XSLT 1.0 to 2.0 doesn't give first text from a tag

我正在尝试使用 XSLT 2.0,但是,标签 <xsl:value-of select=...> 不再给我第一个元素。我得到了 XML 中的所有值。如何转换以下 XSLT 以使用 XSLT 2.0?

<?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" indent="yes"/>

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

    <xsl:template match="Data/ABC">
        <xsl:for-each select=".">
            <Data xmlns="example.com">
                <GEF>
                    <id><xsl:value-of select="id"/></id>
                    <time><xsl:value-of select="time"/></time>
                    <type>test</type>
                </GEF>
            </Data>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

如果我有这个XML:

<Data xmlns="example.com">
    <ABC>
        <id>2</id>
        <time>125622</time>
    </ABC>
</Data>

如果我使用 XSLT 1.0,我会得到:

<Data xmlns="example.com">
    <GEF>
        <id>2</id>
        <time>125622</time>
        <type>test</type>
    </GEF>
</Data>

通常,我会将 2125622 作为 XSLT 中每个标记的单个项目。但是,现在它只获取两个值并输出它们。转换后它甚至不打印标签。我应该在 2.0 中使用什么?我的搜索没有找到任何结果。

这是我在 2.0 中得到的:

<Data xmlns="example.com">

  2
  125622
  test

</Data>

XSLT 和 XPath(1.0 作为更高版本)使用命名空间感知数据模型,因此给定 <Data xmlns="example.com"> Data 元素及其后代位于命名空间 example.com 中,并且您的XSLT 需要考虑到这一点。在 XSLT 2.0 中,您可以使用

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xpath-default-namespace="example.com">

至于您的 Java 代码,请务必使用 namespace aware DocumentBuilderFactory

让您的代码在 XSLT 2.0 下工作的一种方法是 运行 它在向后兼容模式下,您只需将版本号保留为 version="1.0" 即可。如果您知道对 XSLT 1.0 语义的依赖仅适用于样式表的特定部分,那么您可以select巧妙地做到这一点,例如

         <xsl:for-each select="." version="1.0">
            <Data xmlns="example.com">
                <GEF>
                    <id><xsl:value-of select="id"/></id>
                    <time><xsl:value-of select="time"/></time>
                    <type>test</type>
                </GEF>
            </Data>
        </xsl:for-each>

不过,如果可以,最好将代码转换为 2.0 方式。如果您只希望 xsl:value-of 指令处理节点集中的第一项,只需将 [1] 添加到 select 第一项,例如

<id><xsl:value-of select="id[1]"/></id>