【问题标题】:xpath 2.0 selecting elements by attributexpath 2.0 按属性选择元素
【发布时间】:2012-07-26 12:12:57
【问题描述】:

我一直在 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 - 现在开始 Element ist 'sid-B3FD7EE5-043 3-4939-A69F-E74B30FDEB1C' vom Typ xs:untypedAtomic, Typ xs:QName erwartet - =

大致翻译为:

无法设置为目标类型 - 当前元素是 'sid-B3FD7EE5-043 3-4939-A69F-E74B30FDEB1C' 类型为 xs:untypedAtomic,类型 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>

【问题讨论】:

    标签: xpath xslt-2.0 xpath-2.0


    【解决方案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 进行比较很可能会失败,并显示类似于所引用的消息.

    【讨论】:

    • 关于架构的问题,您完全正确。在我从源 xml 文件中删除所有架构信息后,Alova 不再抛出错误,一切都按预期工作。我尝试按照您的描述保留架构并更改变量。但是错误仍然存​​在。不过,感谢您指出我可以如何改进代码。
    【解决方案2】:

    我无法重现该问题。

    这种转变

    <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-12-24
    • 2010-09-18
    • 1970-01-01
    • 2014-08-19
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    相关资源
    最近更新 更多