我正在导入一些XML文件到SQL中,该文件有一个我正在验证的XSD模式。我发现的“问题”是文件中的一些数据包含在CDATA标记中,但相应的XML元素被定义为xsd:token(来自W3Schools--“令牌数据类型也包含字符,但XML处理器将删除换行符,回车符,制表符,前导空格和尾随空格以及多个空格。“)。我注意到,当我在SQL中对一个Typed XML变量运行一个简单的XQuery时,它应用了将多个空格移除到CDATA值的xsd:token规则。在我回到文件供应商之前,我只是想仔细检查一下正确的结果应该是什么。请参见下面的代码片段...XML解析器应该将XSD Schema限制应用于CDATA吗?
CREATE XML SCHEMA COLLECTION dbo.MyTestSchema
AS
N'
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="ROOT">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction base="xsd:anyType">
<xsd:sequence>
<xsd:element ref="Test"
minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="Test" type="TestType"/>
<xsd:simpleType name="TestType">
<xsd:restriction base="xsd:token">
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>'
GO
DECLARE @XMLData varchar(MAX) =
'<ROOT>
<Test><![CDATA[0spaces]]></Test>
<Test><![CDATA[1 space]]></Test>
<Test><![CDATA[2 spaces]]></Test>
<Test><![CDATA[3 spaces]]></Test>
</ROOT>'
DECLARE @XML xml = @XMLData
DECLARE @MyTestXML xml(CONTENT dbo.MyTestSchema) = @XMLData
;WITH WithoutSchema AS
(
SELECT [Test] = NULLIF(T2.n.value('.', 'varchar(10)'), '')
FROM @XML.nodes('/ROOT') AS T1(n)
CROSS APPLY T1.n.nodes('Test') AS T2(n)
),
WithSchema AS
(
SELECT [Test] = NULLIF(T2.n.value('.', 'varchar(10)'), '')
FROM @MyTestXML.nodes('/ROOT') AS T1(n)
CROSS APPLY T1.n.nodes('Test') AS T2(n)
)
SELECT [WithoutSchema] = N.Test, [WithSchema] = Y.Test
FROM WithoutSchema N
INNER JOIN WithSchema Y
ON REPLACE(N.Test, ' ', '') = REPLACE(Y.Test, ' ', '')
GO
DROP XML SCHEMA COLLECTION dbo.MyTestSchema
GO
...结果...
WithoutSchema WithSchema
------------- ----------
0spaces 0spaces
1 space 1 space
2 spaces 2 spaces
3 spaces 3 spaces
...你可以看到,使用非类型化XML变量保存在空间CDATA文本,但使用类型化变量(使用xsd:token)将其删除。如果发生这种情况,我认为xsd只适用于非CDATA值?空格在我们正在加载的数据中有意义,所以如果这是正确的行为,我需要向供应商提出。我试图通过C#读取数据并将该模式应用于作为比较的结果,但我的技能有限,因此没有太多成功。
非常感谢!
感谢您的回复。我将回到我们的供应商,因为我们收到另一个文件(csv),其中列出了“主键”值,我们应该将该文件加入到相关字段中的XML文件中。麻烦的是,在某些情况下,csv文件包含双空格,然后它没有链接到由xml文件加载的值(应用了它们的模式),这已将其转换为仅1空间,所以现在我们得到孤立的数据:) – user2614273