我正在创建我的第一个 XSD,因为我有一个 4MB XML 文件,需要解析为 SQL,并且使用非类型化 XML 处理这么大的文件需要太长时间(一小时后我放弃并取消了查询)。
我拥有的 XML 文件采用以下格式(每个产品都有更多元素,但我缩短了它并创建了一个测试 XML 文件,直到得到正确的结果):
<ITEMS>
<CREATED value="Wed May 2 9:40:38 BST 2012">
<PRODUCT ITEM="0001">
<MODEL>MODELNO1</MODEL>
<BARCODE>5550204425</BARCODE>
<TITLE>Item 1 Title</TITLE>
</PRODUCT>
<PRODUCT ITEM="0002">
<MODEL>MODELNO2</MODEL>
<BARCODE>52614343433</BARCODE>
<TITLE>Item 2 Title</TITLE>
</PRODUCT>
<PRODUCT ITEM="0003">
<MODEL>MODELNO3</MODEL>
<BARCODE>32563533</BARCODE>
<TITLE>Item 3 Title</TITLE>
</PRODUCT>
<PRODUCT ITEM="0004">
<MODEL>MODELNO4</MODEL>
<BARCODE>65135647582</BARCODE>
<TITLE>Item 4 Title</TITLE>
</PRODUCT>
<PRODUCT ITEM="0005">
<MODEL>MODELNO5</MODEL>
<BARCODE>65874112</BARCODE>
<TITLE>Item 4 Title</TITLE>
</PRODUCT>
</CREATED>
</ITEMS>
此 XML 文件是由外部供应商系统自动生成的,我别无选择,只能以当前格式使用它。
我为它创建了这个架构:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ITEMS">
<xs:complexType>
<xs:sequence>
<xs:element name="CREATED">
<xs:complexType>
<xs:sequence>
<xs:element name="PRODUCT" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="MODEL" type="xs:string" maxOccurs="unbounded" />
<xs:element name="BARCODE" type="xs:string" maxOccurs="unbounded" />
<xs:element name="TITLE" type="xs:string" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
在 SQL 中,我首先创建了一个架构集合,如下所示:
IF EXISTS ( SELECT * FROM sys.xml_schema_collections where [name] = 'MyXmlSchema')
DROP XML SCHEMA COLLECTION [MyXmlSchema]
GO
DECLARE @MySchema XML
SET @MySchema =
(
SELECT * FROM OPENROWSET
(
BULK 'C:\test\schema2.xsd', SINGLE_CLOB
) AS xmlData
)
CREATE XML SCHEMA COLLECTION [MyXmlSchema] AS @MySchema
GO
然后我根据架构创建了一个表:
CREATE TABLE [dbo].[XMLProds] (
[MODEL] xml(CONTENT dbo.[MyXmlSchema]) NOT NULL,
[EAN] xml(CONTENT dbo.[MyXmlSchema]) NOT NULL,
[NAME] xml(CONTENT dbo.[MyXmlSchema]) NOT NULL
)
最后,验证 XML:
DECLARE @x2 XML ([MyXmlSchema])
SELECT @x2 = '<copied the code from the test XML file and pasted here>'
验证不喜欢“CREATED”字段中的日期值,没有它我也可以接受,因为它只声明一次并且可以轻松删除。但它也不喜欢每个产品字段中的“ITEM”值,这是问题所在。 2. 这一点不容忽视,因为它出现在每一个项目中(所有 2-3 千个项目)。有办法解决这个问题吗?
为了继续下去,我从测试 XML 中删除了不需要的值,并且验证通过了。然后我执行此语句以尝试填充表:
INSERT INTO XMLProds (MODEL, BARCODE, TITLE)
SELECT X.product.query('MODEL').value('.', 'VARCHAR(20)'),
X.product.query('BARCODE').value('.', 'VARCHAR(50)'),
X.product.query('TITLE').value('.', 'VARCHAR(150)')
FROM (
SELECT CAST(x AS XML)
FROM OPENROWSET(BULK 'C:\test\Products2test.xml', SINGLE_BLOB) AS T(x)) AS T(x)
CROSS APPLY x.nodes('/ITEMS/CREATED/PRODUCT') AS X(product);
..但是遇到了以下错误:
Msg 6909, Level 16, State 1, Line 21 XML Validation: Text node is not allowed at this location, the type was defined with element only content or with simple content. Location: /
任何关于我在这里出错的地方的帮助将不胜感激!提前致谢。
最佳答案
我将从有效的 XSD 开始。您缺少这些属性,这就是您在处理不需要的内容时遇到麻烦的原因。
<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="ITEMS">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="CREATED">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="PRODUCT">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="MODEL" type="xsd:string" />
<xsd:element name="BARCODE" type="xsd:unsignedLong" />
<xsd:element name="TITLE" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="ITEM" type="xsd:unsignedByte" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="value" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
如果仍然不起作用,请告诉我。
关于sql - XSD、XML 到 SQL 导入出现问题 - 此位置不允许文本节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10762044/