我正在试图弄清楚如何针对C#中的模式验证XML。如果XML很简单并且不使用命名空间元素,那么一切似乎都很好。但是,如果它使用XML命名空间,我就会遇到问题。
我想要生成的XML是:
<?xml version="1.0" encoding="utf-8"?>
<SlideDeck xmlns:xy="http://something.com" xy:type="SlideDefinitions">
<Slide>...</Slide>
<Slide>...</Slide>
...
</SlideDeck>
我可以在C#中用相当于:
的东西生成它XmlDocument xDoc = new XmlDocument();
XmlElement xSlideDeck = xDoc.CreateElement("SlideDeck");
xDoc.AppendChild(xSlideDeck);
xSlideDeck.SetAttribute("xmlns:xy", "http://something.com");
xSlideDeck.SetAttribute("type", "http://something.com", "SlideDefinitions");
我可以尝试使用以下方法验证生成的XML文档:
xDoc.Schemas.Add("", "Schema.xsd");
xDoc.Validate(Handler);
要验证的Schema.xsd文件现在非常简单:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="SlideDeck">
<xs:complexType>
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element ref="Slide"/>
</xs:choice>
</xs:sequence>
<xs:attribute name="type" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
... Slide Defined Here ...
</xs:schema>
运行验证时,我收到以下错误:
The 'http://something.com:type' attribute is not declared.
The required attribute 'type' is missing.
我还尝试在XmlDocument中添加一个附加模式,该模式使用相同的模式文件引用http://something.com(希望它可以为'xy'命名空间引入它)。我也尝试过将一个模式添加到正确的uri(省略了没有uri的模式),但是根据其他设置,没有任何验证。我已经尝试使根'SlideDeck'元素也属于http://something.com命名空间。
知道这里可能会发生什么吗?我根本无法改变XML文档的格式。我可以将'SlideDeck'元素和'xy'以及所有其他元素一起制作,但是我不想修改所有代码以额外添加uri到命名空间和前缀来实现这一点。最重要的问题是xmlns:xy定义和xy:type属性,它会提醒收件人注意什么。其他变化是合理的。我也可以控制程序验证的XSD,如果要创建和验证最好通过那里的更改来完成。
答案 0 :(得分:1)
您的架构表明SlideDeck
元素必须具有type
属性 - 都在null命名空间中,而在XML中,SlideDeck
元素具有属性type
in http://something.com
命名空间 - 因此错误。
您应该将XML更改为:
<SlideDeck type="SlideDefinitions">
<Slide>. . . </Slide>
<Slide>. . . </Slide>
. . .
</SlideDeck>
(即摆脱命名空间)。
在替代方案中,您必须更改架构,将其拆分为两个:
<强> typeAttr.xsd:强>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xy="http://something.com"
xmlns="http://something.com"
targetNamespace="http://something.com"
elementFormDefault="qualified"
attributeFormDefault="qualified" >
<xs:attribute name="type" type="xs:string" />
</xs:schema>
<强> slide.xsd:强>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified" xmlns:xy="http://something.com">
<xs:import namespace="http://something.com" schemaLocation="typeAttr.xsd"/>
<xs:element name="SlideDeck">
<xs:complexType>
<xs:sequence>
<xs:choice maxOccurs="unbounded">
<xs:element ref="Slide"/>
</xs:choice>
</xs:sequence>
<xs:attribute ref="xy:type" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="Slide"></xs:element>
</xs:schema>
(在同一目录中)。
通过这种方式,您可以在其单独的命名空间中定义type
属性,并且原始XML可以正确验证。