String-join() 函数受 XML 结构(节点)顺序的影响

String-join() function is affected by order of XML structure (Nodes)

提问人:Siddhant K. 提问时间:11/10/2023 最后编辑:Siddhant K. 更新时间:11/15/2023 访问量:87

问:

我通常广泛使用 String-join() 函数来处理和连接来自数据库的值,但是目前我观察到,如果函数的第二个变量首先在 XSL/XML 结构中获取/存在,而不是第一个变量,那么输出就会与该预期值相反。 例如:

<?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:xsi="http://www.w3.org/2001/XMLSchema-instance" exclude-result-prefixes="#all" version="3.0">  
  <xsl:output method="text" encoding="UTF-8"/>  
  <xsl:template match="/"> 
    <xsl:variable name="b"> 
      <row> 
        <value>2</value> 
      </row> 
    </xsl:variable>  
    <xsl:variable name="a"> 
      <row> 
        <value>1</value> 
      </row> 
    </xsl:variable>  
    <xsl:variable name="c"> 
      <row> 
        <value>1</value> 
      </row> 
    </xsl:variable>  
    <xsl:variable name="d"> 
      <row> 
        <value>2</value> 
      </row> 
    </xsl:variable>  
    <!-- Version a-->  
    <xsl:value-of select="string-join(($a,$b)[. != '']/row/value/text(), ';')"/>  
    <!-- OP - 2;1 -->  
    <!-- Version b-->  
    <xsl:value-of select="formatter:crlf()"/>
    <xsl:value-of select="string-join(($c,$d)[. != '']/row/value/text(), ';')"/>
    <!-- OP - 1;2 -->  
    <!-- Version c-->    
    <xsl:value-of select="formatter:crlf()"/>
    <xsl:value-of select="string-join(($a[. != '']/row/value/text(),$b[. != '']/row/value/text()), ';')"/> 
    <!-- OP - 1;2 -->  
  </xsl:template> 
</xsl:stylesheet>

在这里,我有四个变量 a、b、c、d,值分别为 1、2、1、2 和 3 个版本的 string-join() 函数。 对于第一个版本,我得到输出 2;1 这不是我所期望的,似乎由于 b 是在 a 之前声明的,因此在获取值时,b 被更早地获取,并且按照该顺序连接并打印。 对于版本 b,我得到了预期的,因为 c 是在 d 之前声明的。 对于版本 c,我做了一个调整,现在能够得到正确的序列。

我的期望是这不应该发生。在实际生产场景中,我有许多来自数据库的值,这些值是异步获取的,并且在需要时,因此当我执行string-join()操作时,我期望正确的输出。

我验证这不是由于SAXON或XPATH问题,因为我尝试了带有XPATH 3的SAXON 10和带有XPATH 2的SAXON 9,并且得到了相同的结果。

让我知道你们的想法,我能做什么?

  • 注意:我无法更改 string-join() 函数,因为这会残酷地影响许多不同地方的生产环境变量。
字符串 XPath XSLT 串联 Saxon

评论

0赞 michael.hor257k 11/11/2023
FWIW,我得到了你的“版本 a”的结果和 .使用撒克逊 10.6 HE。1;22;1string-join(($b,$a)/row/value/text(), ';')

答:

3赞 Martin Honnen 11/10/2023 #1

您正在使用按文档顺序对节点进行排序的运算符,因此在定义顺序时,使用 of 确保使用文档顺序,只是我认为来自不同文档的节点的文档顺序基本上是未定义的。/string-join(($a,$b)[. != '']/row/value/text(), ';')$a,$b/row/value/text()

您可以使用代替 例如.!/<xsl:value-of select="string-join(($a,$b)[. != '']!row!value!text(), ';')"/>

请参阅撒克逊 HE 11撒克逊 HE(C) 12 的在线示例。

评论

0赞 Daniel Haley 11/10/2023
我从未见过这样使用的地图运算符。我必须记住,您可以像路径运算符一样使用它。非常方便!我也可能会去规范中阅读更多关于它的信息。我没有充分使用它来了解所有细节。感谢马丁的灵感!
3赞 Michael Kay 11/10/2023
“/”的使用是如此成熟,以至于人们不会想到“!”是一个更简单的运算符,通常以更少的努力完成您想要的操作。
0赞 Siddhant K. 11/15/2023
感谢您@DanielHaley回答,它在我的系统中与 SAXON 10.6 XSLT 3.0 完美配合。只是为了更多信息:在不更改 string-join() 函数的情况下这可能吗?
0赞 Daniel Haley 11/15/2023
@SiddhantK。- 这实际上是马丁的答案。我认为如果不更改 string-join() 就无法解决您的问题(出于答案中给出的原因)。此外,我不认为从答案中删除示例可以改善答案。它很可能会帮助未来的访问者获得这个答案。