XML - XSLT - count() 函数内的 document() 函数

Posted

技术标签:

【中文标题】XML - XSLT - count() 函数内的 document() 函数【英文标题】:XML - XSLT - document() function inside count() function 【发布时间】:2018-12-21 17:14:18 【问题描述】:

我在另一篇文章中问了一个类似的问题,但我决定制作这个新问题,因为这是一个不同的问题。我正在使用两个 XML 输入文件,使用 document() 函数来访问其中一个(外部文件)。我正在尝试在count() 函数中使用document() 函数,但我不知道为什么它不起作用...这是 XML 输入文档:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <childs>
        <child ID="1" name="John" />
        <child ID="2" name="Marie"/>
        <child ID="3" name="Joseph"/>
    </childs>
</parent>

这是我与 document() 函数一起使用的外部 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design">
    <property name="units">in</property>
    <text-property name="displayName">Daisy</text-property>
    <text-property name="text">Just plain text</text-property>
    <propList>
        <prop name="prop1"/>
        <prop name="prop2"/>
        <prop name="prop3"/>
        <prop name="prop4"/>
        <prop name="prop5"/>
    </propList>
</report>

所以我要做的是获取属性值为displayNametext-property元素的值,然后计算prop元素的数量,生成一个新的child元素。这是我的 XSLT 代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:ecd="http://www.eclipse.org/birt/2005/design"
  exclude-result-prefixes="xs ecd"
  expand-text="yes"
  version="3.0">

    <xsl:output indent="yes" />

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="parent/childs/child[last()]">

    <xsl:next-match/>
        <child>
            <xsl:attribute name="ID">
                <xsl:value-of select="count(preceding-sibling::child)+2" />
            </xsl:attribute>
            <xsl:attribute name="name">
                <xsl:value-of select="document('inputStack.xml')/ecd:report/ecd:text-property[@name = 'displayName']"/>
            </xsl:attribute>
            <!--new attribute-->
            <xsl:attribute name="nProps">
                <xsl:value-of select="count(document('inputStack.xml')/ecd:report/ecd:propList/(preceding-sibling::ecd:prop[last()]))+1"/>
            </xsl:attribute>
        </child>
    </xsl:template>

</xsl:stylesheet>

所以这是我目前得到的输出:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <childs>
        <child ID="1" name="John"/>
        <child ID="2" name="Marie"/>
        <child ID="3" name="Joseph"/>
        <child ID="4" name="Daisy" nProps="1"/>
    </childs>
</parent>

如你所见,我得到属性name 的值是正确的(Daisy),但属性nProps 的值是错误的,应该是5,

我在 count 函数内的 XPATH 中做错了吗?

谢谢!

亚历山大·哈辛托

【问题讨论】:

count(document('inputStack.xml')/ecd:report/ecd:propList/ecd:prop) 提供了什么?试图理解应用preceding-sibling 轴背后的逻辑。 @AniketV 我正在尝试计算 prop 元素的数量,这就是为什么我在 prop[last()] 中使用前兄弟轴的原因,这样它就可以为我提供所有兄弟姐妹在最后一个 prop 元素之前,然后添加 +1 @imran 我不是要计算子元素,而是要计算外部文件中的 prop 元素 只做count(document('inputStack.xml')/ecd:report/ecd:propList/ecd:prop)有什么问题? @TimC 我不知道为什么我把它弄得这么复杂,谢谢,这行得通! 【参考方案1】:

表达式ecd:propList/(preceding-sibling::ecd:prop[last()]) 不选择任何内容(一个空节点集),因为ecd:propList 元素没有任何前面的名为ecd:prop 的同级元素。

【讨论】:

是的,我没有用错前兄弟轴

以上是关于XML - XSLT - count() 函数内的 document() 函数的主要内容,如果未能解决你的问题,请参考以下文章

xslt中count属性的范围是多少?

将模板内的变量初始化为xml指定的次数

使用 XSLT 3.0 的 JSON 到 XML - 如何加载 JSON 源并调用 json-to-xml 函数?

如何停止 xslt3.0 的 xml-to-json() 函数将数字转换为指数表示法

XSLT 3.0 - 无法在 XSLT 3.0 xml-to-json() 中获取对象数组

document() 函数在 XSLT 中如何工作?