考虑这个xml文档:
DECLARE @X XML (DOCUMENT search.SearchParameters) = '<parameters xmlns="http://www.educations.com/Search/Parameters.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<parameter xsi:type="category" categoryID="38" />
</parameters>';
我想访问“type”属性的值。
根据此blog post,xsi:type
属性很特殊,通常的关键字/功能无法访问。
我该怎么办?
PS:我试过
WITH XMLNAMESPACES (
'http://www.educations.com/Search/Parameters.xsd' as p,
'http://www.w3.org/2001/XMLSchema-instance' as xsi)
SELECT @X.value('(/p:parameters/p:parameter/@xsi:type)[1]','nvarchar(max)')
但它不起作用。
答案 0 :(得分:2)
如果没有指定集合,这对我来说很好:
DECLARE @X XML
SET @x = N'
<parameters xmlns="http://www.educations.com/Search/Parameters.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<parameter xsi:type="category" categoryID="38" />
</parameters>'
;
WITH XMLNAMESPACES
(
'http://www.educations.com/Search/Parameters.xsd' as p,
'http://www.w3.org/2001/XMLSchema-instance' as xsi
)
SELECT @X.value('(/p:parameters/p:parameter/@xsi:type)[1]','nvarchar(max)')
您能否发布search.SearchParameters
的内容?
<强>更新强>
在架构绑定XML
上,这似乎是不可能的。
您可以将列转换为freetype XML
:
WITH XMLNAMESPACES
(
'http://www.educations.com/Search/Parameters.xsd' as p,
'http://www.w3.org/2001/XMLSchema-instance' as xsi
)
SELECT CAST(@X AS XML).value('(/p:parameters/p:parameter/@xsi:type)[1]','nvarchar(max)')
(但您无法在列上使用任何XML
索引),或对特定类型执行布尔检查:
WITH XMLNAMESPACES
(
'http://www.educations.com/Search/Parameters.xsd' as p
)
SELECT @X.query('(/p:parameters/p:parameter)[1] instance of element(*, p:category?)')
答案 1 :(得分:0)
我知道这是一个老问题,但是我昨天遇到了这个问题,并且在SQL中找不到这个限制的明显答案。但是,如果您可以控制架构,我已经确定了解决方法。
只需在每个子类型上创建一个具有相同名称的属性(我的示例中的widgetType)。
将每个属性设置为一个简单类型的xsi:string并对其设置限制,因此唯一的值是您的子类型的名称。此外,将其设置为属性的默认值。
如果将此架构绑定到xml数据列,则始终可以查询基本上镜像xsi:type值的此属性。
我承认这不太理想,但它比将值转换为无类型并且失去索引的好处更好。
以下是一个例子:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/XMLSchema.xsd"
xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="widget"
type="baseWidget" />
<xs:complexType name="baseWidget"
abstract="true"></xs:complexType>
<xs:complexType name="widgetA">
<xs:complexContent>
<xs:extension base="baseWidget">
<xs:attribute name="widgetType"
default="widgetA">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="widgetA" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="widgetB">
<xs:complexContent>
<xs:extension base="baseWidget">
<xs:attribute name="widgetType"
default="widgetB">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="widgetB" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
如果要在没有widgetType属性的情况下将xml条目放入绑定到此模式的表中,则SQL会因默认值而自动添加它。它始终可供您查询。
<?xml version="1.0" encoding="utf-8"?>
<widget xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="widgetA"
widgetType="widgetA"
xmlns="http://tempuri.org/XMLSchema.xsd" />