为什么我的XML无法在SQL Server 2008中的类型化XML列中进行验证?
|
超短版:
当我快写完问题时,我解决了这个问题。答案很快就会到来。
精简版:
为什么SQL Server拒绝将我的XML插入类型化XML列中? XML是使用.NET 4中的“ 0”生成的。
更长的版本:
我有一个可以使用
XmlSerializer
成功进行序列化的类。更具体地说,我可以使用XmlSerializer
成功序列化该类的数组。
我在SQL Server 2008表中有一个XML列。如果我只是使用无类型的XML列,则插入XmlSerializer.Serialize
的输出效果很好(我使用的是Entity Framework,它将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[]
类型。
现在,ѭ1产生如下输出:
<?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验证?
没有找到相关结果
已邀请:
1 个回复
弦砂牧扁
更改为
并添加
来更改XSD中的
元素:
在
类型的每个
标签中添加
。我误解了此参考文档,是指将
和
自动应用于其中的所有
标签。如果那是正确的,则SQL Server似乎无法识别出它。因此,要通过验证,我必须使每个元素类似于
因为并非所有标签都将出现在每个“ 31”元素中。 在
元素内的
类型中添加名称空间前缀
:
创建我的“ 1”时,同时使用类型和默认名称空间进行序列化和反序列化:
我以前曾经尝试过,但是现在我知道这是最终解决方案的一部分。 呼叫
时,请执行以下操作:
在
类本身上,添加属性
在序列化中包含的“ 31”的每个属性上,添加属性
最后,
已经使用custom50ѭ实现了自定义序列化,而在我开始使用此功能时,
已实现。这个事实可能使上面的属性添加变得不必要,但是我尚未测试该断言。无论哪种方式,都必须在
方法中使用
其中“ 54”是要序列化的属性的名称,“ 55”是其值。不必使用指定名称空间前缀的“ 56”形式;序列化程序会自动包含正确的前缀。
方法已经使用
来检索元素名称,因此无需进行任何更改即可处理名称空间。 对不起,项目符号格式;列表似乎不能很好地与代码块配合使用。 希望这对某人在Google搜索中有所帮助。