我有一个简单的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不能工作?
答案 0 :(得分:0)
似乎您很了解,这不是说服解析器仅将一件事传递给value()
的常见问题。正如您所观察到的,此问题特定于键入的XML 。
使用Google我发现this ancient blogpost包含有前途的文字
rt是XQuery 1.0 / XPath 2.0数据模型的一部分。
大多数人都那样做。当您使用带text()节点测试的无类型XML和XPath表达式进行示例时,真正的乐趣就开始了。当使用无类型XML时,text()可以很好地工作,但是对具有简单内容的类型XML失败
它讨论了SQL Books Online和SQL Server 2005 XML Best Practices论文,我认为是this book here。我没有寻找最新的参考资料。但是使用我在那找到的东西,我已经能够解决您的问题:简单替换
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的值,而是想要字符串。所以我们给它一个字符串。