0

我一直在 xpath 1.0 中使用以下 xpath 选择

<xsl:variable name="id"><xsl:value-of select="./@id" /></xsl:variable>
preceding::exm:messageFlow[@sourceRef = $id]/@targetRef

这工作得很好,完全符合我的要求。但是,我开始将 XSLT 2.0 与 xPath 2.0 结合使用,但这不再起作用(使用 Altova XML 处理器)我收到以下错误:

Kann nicht mit Ziel-Typ besetzt werden - 当前元素 ist 'sid-B3FD7EE5-043 3-4939-A69F-E74B30FDEB1C' vom Typ xs:untypedAtomic, Typ xs:QName erwartet - =

大致翻译为:

无法设置为目标类型 - 当前元素是 xs:untypedAtomic 类型的“sid-B3FD7EE5-043 3-4939-A69F-E74B30FDEB1C”,预期类型为 xs:QName -

以前我对这个选择有类似的问题:

following::exm:*[exm:incoming = $out] | preceding::exm:*[exm:incoming = $out]

再次在 xpath 1.0 中工作,但在 xPath 2.0 中返回类似的错误后将其更改为

following::exm:*[exm:incoming/text() = $out] | preceding::exm:*[exm:incoming/text() = $out]

它也适用于 xPath 2.0。我确实尝试过对属性做类似的事情,但没有奏效

相应 XML 的一小部分摘录:

<messageFlow id="sid-80B618A4-E6BF-4438-AF5D-5111AD308FE6" name="" sourceRef="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C" targetRef="sid-6EB2DB76-CC19-48AD-A073-D37C7489F211"/>
<task completionQuantity="1" id="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C" isForCompensation="false" name="call service" startQuantity="1">
     <incoming>sid-2B2BA651-B5BA-4195-9B5B-E6855B1138F4</incoming>
     <incoming>sid-DA4B86E8-C3F2-497C-8C0D-218E95CE9FD1</incoming>
     <outgoing>sid-008948DE-BA59-4897-AC37-2C3AA63DCD82</outgoing>
</task>
4

2 回答 2

1

我无法重现该问题。

这种转变

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="task">
    <xsl:variable name="id"><xsl:value-of select="./@id" /></xsl:variable>

    <xsl:variable name="vResult"
     select="preceding::messageFlow[@sourceRef = $id]/@targetRef"/>

    <xsl:value-of select="$vResult"/>
 </xsl:template>
</xsl:stylesheet>

当应用于以下文档时(提供的片段包装在单个顶部元素中并剥离任何未定义的命名空间):

<t>
    <messageFlow id="sid-80B618A4-E6BF-4438-AF5D-5111AD308FE6"
    name="" sourceRef="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C"
    targetRef="sid-6EB2DB76-CC19-48AD-A073-D37C7489F211"/>
    <task completionQuantity="1" id="sid-B3FD7EE5-0433-4939-A69F-E74B30FDEB1C"
    isForCompensation="false" name="call service" startQuantity="1">
         <incoming>sid-2B2BA651-B5BA-4195-9B5B-E6855B1138F4</incoming>
         <incoming>sid-DA4B86E8-C3F2-497C-8C0D-218E95CE9FD1</incoming>
         <outgoing>sid-008948DE-BA59-4897-AC37-2C3AA63DCD82</outgoing>
    </task>
</t>

当同时使用 Altova2011 和 Saxon 9.1.07 运行时,会产生预期的正确结果,并且不会引发错误

sid-6EB2DB76-CC19-48AD-A073-D37C7489F211
于 2012-07-26T12:54:17.910 回答
1

我想知道您是否有一个架构将@id 属性声明为 QName 类型?

使用此变量声明:

<xsl:variable name="id"><xsl:value-of select="./@id" /></xsl:variable>

您正在新的结果树片段中创建 @id 属性的副本。这是完全没有必要的;通过使变量成为对现有属性的简单引用,几乎可以肯定您的需求会得到更好的满足,因此:

<xsl:variable name="id" select="@id" />

通过制作副本,您不仅会编写不必要的代码并产生不必要的运行时成本(构建新树是一项昂贵的操作),而且还会丢失类型信息。如果我的猜想是正确的,@id 是 xs:QName 类型,那么原子化后的变量 $id 将是 xs:untypedAtomic 类型,并且将它与 xs:QName 进行比较很可能会失败,并显示类似于引用的消息.

于 2012-07-26T22:18:31.210 回答