对子树进行排序并将其存储在 xsl:variable 中

发布于 2024-09-15 03:52:56 字数 1710 浏览 1 评论 0原文

我正在使用 XSL 样式表,并且尝试使用显示的方法 此处将排序的子树存储为变量。我使用 saxon 8.7 和 xml-maven-plugin 来转换我的 XML 文件。这是我的代码:

<xsl:variable name="miniDays">
    <xsl:for-each select="//day[position() > $firstPosToShow]">
        <xsl:sort select="@date" order="descending" />
        <xsl:copy-of select=".|@*" />
    </xsl:for-each>
</xsl:variable>

当我运行样式表时,出现以下错误:

Error at xsl:copy-of on line 598 of file:/D:/home/Projects/src/main/xsl/site.xsl:
  XTDE0420: Cannot create an attribute node (date) whose parent is a document node

如果我只是将子树设置为变量而不进行排序,它可以工作,但未排序:

<xsl:variable name="miniDays" select="//day[position() > $firstPosToShow]" />

如果我将 copy-of 语句的 select 设置为“ .”,它超过了这一点,但是当我实际尝试使用变量数据时,它给了我一个错误。这是它的使用方式:

<xsl:for-each select="exsl:node-set($miniDays)">
    <xsl:variable name="in" select="local:calculate-total-in-days(.)" />
    <!-- do some stuff with the var -->
</xsl:for-each>

错误:

Error on line 676 of file:/D:/home/Projects/src/main/xsl/site.xsl:
  XPTY0004: Required item type of first argument of local:calculate-total-in-days() is element(); supplied value has item type document-node()

函数:

<xsl:function name="local:calculate-total-in-days">
    <xsl:param name="days" as="element()*" />
    <!-- Do some calculations -->
</xsl:function>

我是否错误地使用了 exsl:node-set?副本的选择中应该包含什么“。”或“.|@*”?

I'm working with an XSL stylesheet, and I'm trying to use the method shown here to store a sorted subtree as a variable. I'm using saxon 8.7 vis the xml-maven-plugin to transform my XML file. Here's the code that I have:

<xsl:variable name="miniDays">
    <xsl:for-each select="//day[position() > $firstPosToShow]">
        <xsl:sort select="@date" order="descending" />
        <xsl:copy-of select=".|@*" />
    </xsl:for-each>
</xsl:variable>

When I run the stylesheet, I get the following error:

Error at xsl:copy-of on line 598 of file:/D:/home/Projects/src/main/xsl/site.xsl:
  XTDE0420: Cannot create an attribute node (date) whose parent is a document node

If I just set the subtree to the variable without sorting, it works, but it's not sorted:

<xsl:variable name="miniDays" select="//day[position() > $firstPosToShow]" />

If I set the copy-of statement's select to ".", it gets past that point, but gives me an error later on when I actually try to use the variable data. Here's how it's being used:

<xsl:for-each select="exsl:node-set($miniDays)">
    <xsl:variable name="in" select="local:calculate-total-in-days(.)" />
    <!-- do some stuff with the var -->
</xsl:for-each>

And the error:

Error on line 676 of file:/D:/home/Projects/src/main/xsl/site.xsl:
  XPTY0004: Required item type of first argument of local:calculate-total-in-days() is element(); supplied value has item type document-node()

The function:

<xsl:function name="local:calculate-total-in-days">
    <xsl:param name="days" as="element()*" />
    <!-- Do some calculations -->
</xsl:function>

Am I using exsl:node-set incorrectly? And what should be in the copy-of's select, "." or ".|@*"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夏至、离别 2024-09-22 03:52:57

您的代码存在一些问题

  1. .这将选择文档中 day 子元素集中位于 $firstPosToShow+1 或更大位置的每个 day 元素。它的父级!您很可能想要 (//day)[position() >= $firstPosToShow]

  2. 。这会复制当前元素,同时也会复制其属性。仅当父元素是元素时才可以复制属性。情况并非如此,因为无类型变量内部的操作会创建临时树(文档),并且文档节点不能具有属性。正确的指令是:

  3. 列表项中的代码如下:

表达式 exsl:node-set($miniDays) 再次为 document-node() 类型,并且 > 仅选择一个(此)节点。这解释了引发的错误,因为 local:calculate-total-in-days(.) 需要一个元素参数,但传递了一个文档节点。

正确的代码是

<xsl:for-each select="exsl:node-set($miniDays)/*"> 
    <xsl:variable name="in" select="local:calculate-total-in-days(.)" /> 
    <!-- do some stuff with the var --> 
</xsl:for-each>

另外,XSLT 2.0 中不需要 exslt:node:set(),因为 XSLT 2.0 中没有 RTF 类型,事实上也不是Saxon 9.x 支持。 因此,正确的代码为

<xsl:for-each select="$miniDays/*"> 
    <xsl:variable name="in" select="local:calculate-total-in-days(.)" /> 
    <!-- do some stuff with the var --> 
</xsl:for-each>

或者,您可以考虑将 $miniDays 的类型显式指定为 element()*< /code> 这将简化代码 - 不需要使用 $miniDays/* - 只需使用 $miniDays

There are a number of problems with your code:

  1. <xsl:for-each select="//day[position() > $firstPosToShow]"> . This will select every day element in the document that is at position $firstPosToShow+1 or bigger in the set of day children of its parent! Most probably you want (//day)[position() >= $firstPosToShow]

  2. <xsl:copy-of select=".|@*" /> . This copies the current element, but also copies its attributes. An attribute can be copied only when the parent is an element. This is not the case as the operations inside an untyped variable create a temporary tree (a document) and a document node cannot have attributes. The correct instruction is: <xsl:copy-of select="." />

  3. List itemIn the following code:

the expression exsl:node-set($miniDays) again is of type document-node() and the <xsl:for-each> selects just one (this) node. This explains the raised error, because local:calculate-total-in-days(.) expects an element-argument but is passed a document node.

The correct code is:

<xsl:for-each select="exsl:node-set($miniDays)/*"> 
    <xsl:variable name="in" select="local:calculate-total-in-days(.)" /> 
    <!-- do some stuff with the var --> 
</xsl:for-each>

Also, exslt:node:set() is not required in XSLT 2.0, because there is no RTF type in XSLT 2.0, and in fact is not supported in Saxon 9.x. Therefore, the correct code will be:

<xsl:for-each select="$miniDays/*"> 
    <xsl:variable name="in" select="local:calculate-total-in-days(.)" /> 
    <!-- do some stuff with the var --> 
</xsl:for-each>

Alternatively, you may consider specifying the type of $miniDays explicitly as element()* and this will simplify the code -- it would not be necessary to use $miniDays/* -- just $miniDays

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文