繁体   English   中英

从带有* typed * XML的父节点读取属性时,XQuery错误(value()需要单例)

[英]XQuery Error when reading attribute from parentnode with *typed* XML (value() requires a singleton)

我有一个简单的XML:

DECLARE @x1 xml = '<r>
    <o a="1">
        <o a="2">
        </o>
    </o>
</r>';

并选择以下内容:

SELECT r.o.value('(../@a)[1]','varchar(20)') FROM @x1.nodes('/r//o') r(o);

一切都很好:

NULL
1

当我使用输入的XML时:

CREATE XML SCHEMA COLLECTION [dbo].test AS '
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="r">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:sequence>
                        <xsd:element name="o" type="o" minOccurs="0" maxOccurs="unbounded" />
                    </xsd:sequence>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>
    <xsd:complexType name="o">
        <xsd:complexContent>
            <xsd:restriction base="xsd:anyType">
                <xsd:sequence>
                    <xsd:element name="o" type="o" minOccurs="0" maxOccurs="unbounded" />
                </xsd:sequence>
                <xsd:attribute name="a" type="xsd:string" />
            </xsd:restriction>
        </xsd:complexContent>
    </xsd:complexType>
</xsd:schema>'
GO

DECLARE @x2 xml(dbo.test) = '<r>
    <o a="1">
        <o a="2">
        </o>
    </o>
</r>';

SELECT r.o.value('(../@a)[1]','varchar(20)') FROM @x2.nodes('/r//o') r(o);

我得到了错误:

XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'

为什么无类型的XML有效而无类型的XML有效?

您似乎似乎很了解,这并不是说服解析器只有一件事传递给value()的通常问题。 如您所见 ,此问题特定于类型化XML

使用谷歌,我发现了这个古老的博客文章 ,里面有前途的文字

rt是XQuery 1.0 / XPath 2.0数据模型的一部分。

大多数人都这样。 当您使用带text()节点测试的无类型XML和XPath表达式进行示例时,真正的乐趣就开始了。 当使用无类型的XML时,text()可以很好地工作,但是无法处理具有简单内容的带类型的XML

它讨论了SQL联机丛书和SQL Server 2005 XML最佳实践论文,我认为 这本书 我没有寻找最新的参考资料。 但使用的是什么,我发现那里,我已经能够解决您的问题:简单更换

SELECT r.o.value('(../@a)[1]','varchar(20)') FROM @x2.nodes('/r//o') r(o);

SELECT r.o.value('fn:string(../@a)[1]','varchar(20)') FROM @x2.nodes('/r//o') r(o);

基本上, value()不喜欢被赋予typed-xml-type的值,而是需要字符串。 所以我们给它一个字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM