【问题标题】:Trouble with XSD, XML to SQL Import - Text node is not allowed in this locationXSD 问题,XML 到 SQL 导入 - 此位置不允许文本节点
【发布时间】:2012-06-01 11:40:32
【问题描述】:

我正在创建我的第一个 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>'

验证不喜欢“创建”字段中的日期值,我可以不用它,因为它只声明一次并且可以轻松删除。但它也不喜欢每个产品字段中的“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);

..但遇到以下错误:

消息 6909,级别 16,状态 1,第 21 行 XML 验证:文本节点不是 在此位置允许,类型仅使用元素定义 内容或简单的内容。地点:/

对于我在这里出错的地方的任何帮助将不胜感激!提前致谢。

【问题讨论】:

    标签: sql sql-server xml xsd xsd-validation


    【解决方案1】:

    我将从一个有效的 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>
    

    如果还是不行,请告诉我。

    【讨论】:

    • 感谢您的回复。我将 ITEM 属性更改为字符串,这使 XML 通过了验证,所以您已经解决了这个问题。仍然得到相同的 SQL 错误。不过,这已经缩小了范围,我还有更多工作要做,所以谢谢
    • 我会使用 XML 验证器(Visual Studio 有一个支持 XSD 验证的内置 XML 编辑器)首先针对您“猜测的”XSD 验证 XML;现在忽略 SQL 方面。在独立于处理基础架构成功验证 XML(并证明 XSD 是正确的)后,再试一次。否则,你就是在浪费时间。 4MB 不算大;如果文件有 4GB,我仍然会这样做,只是在“流”读取并独立验证每个节点(“记录”)之后,它会以编程方式进行。
    猜你喜欢
    • 2010-10-01
    • 2017-12-23
    • 2021-04-22
    • 1970-01-01
    • 2012-08-21
    • 2016-04-13
    • 2012-03-26
    • 2018-03-12
    • 2017-11-12
    相关资源
    最近更新 更多