【发布时间】:2011-04-13 22:21:38
【问题描述】:
超短版:
当我快写完问题时,我解决了这个问题。很快就会有答案。
短版:
为什么 SQL Server 拒绝将我的 XML 插入到类型化的 XML 列中? XML 是在 .NET 4 中使用 System.Xml.Serialization.XmlSerializer 生成的。
更长的版本:
我有一个可以使用XmlSerializer 成功序列化的类。更具体地说,我可以使用XmlSerializer 成功序列化该类的数组。
我在 SQL Server 2008 表中有一个 XML 列。如果我只使用无类型的 XML 列,则插入 XmlSerializer.Serialize 的输出可以正常工作(我使用的是实体框架,它将 XML 列转换为类型 string)。但是,我想将该列改为类型化 XML 列。当我这样做时,无论我尝试什么,我似乎都无法从序列化程序中获取 XML 以成功验证。
这是我用来在 SQL Server 中创建类型化 XML 列的(略微混淆的)XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ArrayOfMyObject"
targetNamespace="http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd"
xmlns="http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<xs:complexType name="MyObject">
<xs:all minOccurs="0" maxOccurs="1">
<xs:element name="CD" type="xs:int" />
<xs:element name="CI" type="xs:string" />
<xs:element name="CT" type="xs:int" />
<xs:element name="CY" type="xs:int" />
<xs:element name="LD" type="xs:int" />
<xs:element name="SomeName" type="xs:string" />
<xs:element name="SomeNumber" type="xs:string" />
<xs:element name="SD" type="xs:int" />
<xs:element name="ZP" type="xs:string" />
<xs:element name="State">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[A-Z][A-Z]" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
<xs:element name="ArrayOfMyObject">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="MyObject" type="MyObject" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
我在 SQL Server 中创建了架构集合:
CREATE XML SCHEMA COLLECTION [dbo].[MySchemaCollection] AS
'<The XSD from above>'
(在这里进行明显的替换)。请注意,我做了不:
CREATE XML SCHEMA COLLECTION [dbo].[MySchemaCollection] AS
N'<The XSD from above which now gives an error>'
因为NVARCHAR 类型与 utf-8 的组合会导致 SQL Server 产生如下错误:
消息 9402,第 16 级,状态 1,第 3 行
XML解析:第1行,第39个字符,无法切换编码
现在,我重新创建表,相关列是:
[MyXmlColumn] [xml](DOCUMENT [dbo].[MySchemaCollection]) NULL
我希望我插入的是DOCUMENT,但我也尝试将列创建为CONTENT,但无济于事。
我将XmlSerializer 创建为
_xml = new XmlSerializer(typeof(MyObject[]));
并使用
调用序列化程序XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("t", "http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd");
_xml.Serialize(serializationStream, graph, ns);
当然,serializationStream 是输出流(在本例中为 MemoryStream),graph 的类型为 MyObject[]。
现在,XmlSerializer 产生如下输出:
<?xml version="1.0" ?>
<ArrayOfMyObject xmlns:t="http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd">
<MyObject>
<LD>1</LD>
<SomeName>SOME CITY 04</SomeName>
<SomeNumber>04</SomeNumber>
</MyObject>
<MyObject>
<LD>1</LD>
<SomeName>SOME CITY 05</SomeName>
<SomeNumber>05</SomeNumber>
</MyObject>
<MyObject>
<LD>1</LD>
<SomeName>SOME CITY 07</SomeName>
<SomeNumber>07</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>BANKS-FREMONT</SomeName>
<SomeNumber>BF</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>BENNINGTON</SomeName>
<SomeNumber>B000</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>CENTER</SomeName>
<SomeNumber>CE</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>FRANKLINE MAXFIELD CITY</SomeName>
<SomeNumber>FR</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>FREDERIKA LEROY CITY OF</SomeName>
<SomeNumber>FD</SomeNumber>
</MyObject>
<MyObject>
<LD>18</LD>
<SomeName>HARLAN</SomeName>
<SomeNumber>HL</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>ATLANTIC 2 AND GROVE</SomeName>
<SomeNumber>AT2</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>BRIGHTON/MARNE/GROVE 1/P</SomeName>
<SomeNumber>MR</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>EDNA/NOBLE/PLEASANT/GRIS</SomeName>
<SomeNumber>GS</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>FRANKLIN/WIOTA/GRANT/ANI</SomeName>
<SomeNumber>AN</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>MASSENA AND CITY</SomeName>
<SomeNumber>MS</SomeNumber>
</MyObject>
<MyObject>
<CT>15</CT>
<SomeName>UNION & CUMBERLAND</SomeName>
<SomeNumber>CU</SomeNumber>
</MyObject>
<MyObject>
<CD>3</CD>
<State>IA</State>
</MyObject>
<MyObject>
<CD>5</CD>
<State>IA</State>
</MyObject>
<MyObject>
<CT>1</CT>
<State>IA</State>
</MyObject>
<MyObject>
<CT>2</CT>
<State>IA</State>
</MyObject>
<MyObject>
<CT>5</CT>
<State>IA</State>
</MyObject>
</ArrayOfMyObject>
当我调用Context.SaveChanges 时,我得到一个异常,其内部异常消息是:
XML 验证:未找到元素“ArrayOfMyObject”的声明。位置:/*:ArrayOfMyObject[1]
我尝试使用许多不同的命名空间选项调用和/或创建序列化程序,但我得到相同或类似的错误(声称 {http://www.myproduct.com/2011/04/08/ArrayOfMyObject.xsd}ArrayOfMyObject 是预期的,但找到了 ArrayOfMyObject,或者相反反之亦然)。
我需要进行哪些更改才能使来自序列化程序的 XML 在 SQL Server 2008 上通过 XML 验证?
【问题讨论】:
标签: sql-server-2008 .net-4.0 entity-framework-4 xsd xmlserializer