我有以下(错误的)Xml:
<jobs>
<job>
<id>1</id>
<state><![CDATA[IL]]></state>
</job>
<job>
<id>2</id>
</job>
</jobs>
id和state节点都是需要的项目。我为它写了一个Xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="importvalidator"
elementFormDefault="qualified"
targetNamespace="http://foo.org/importvalidator.xsd"
xmlns="http://foo.org/importvalidator.xsd"
xmlns:mstns="http://foo.org/importvalidator.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="jobs">
<xs:complexType>
<xs:sequence>
<xs:element name="job" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:all>
<xs:element name="id" type="xs:string" minOccurs="1"/>
<xs:element name="state" type="xs:string" minOccurs="1"/>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
它仍然可以验证为结构有效的Xml。我在这里缺少什么?
Update1:我正在使用的代码是C#:
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("http://foo.org/importvalidator.xsd", "validator.xsd");
XDocument doc = XDocument.Load(fileName);
if (doc == null | doc.Root == null)
{
throw new ApplicationException("xml error: the referenced stream is not xml.");
}
doc.Validate(schemas, (o, e) =>
{
throw new ApplicationException("xsd validation error: xml file has structural problems");
});
答案 0 :(得分:3)
请格式化您的xml,以便更容易阅读 - 就像这样:
<jobs>
<job>
<id>1</id>
<state><![CDATA[IL]]></state>
</job>
<job>
<id>2</id>
</job>
</jobs>
我认为你实际上并没有对它进行验证 - 命名空间意味着即使在第二个“<state>
”中使用“<job>
”,XML也无法验证。具体来说,XSD的目标名称空间为“http://foo.org/importvalidator.xsd
”,但XML没有给出名称空间。
设置一个简单的XSD和XML测试用例,你肯定知道它会失败 - 用它来追踪你没有验证的原因。
此外,您的XSD缺少元素和架构的关闭标记,因此它应该给出错误 - 或者它只是错误粘贴: - )
您可以从架构中删除targetNamespace:
<xs:schema id="importvalidator"
elementFormDefault="qualified"
targetNamespace="http://foo.org/importvalidator.xsd ← DELETE THIS"
xmlns="http://foo.org/importvalidator.xsd"
xmlns:mstns="http://foo.org/importvalidator.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
所以它看起来像这样:
<xs:schema id="importvalidator"
elementFormDefault="qualified"
xmlns="http://foo.org/importvalidator.xsd"
xmlns:mstns="http://foo.org/importvalidator.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
PS:有人知道你是否/如何用SO的降价突出显示部分源代码?
答案 1 :(得分:2)
@ 13ren有正确的答案。如果节点与任何架构都不匹配,则不会出错。这只是一个警告。我可以在下面的代码中看到警告:
private static void ValidateDocument(XmlSchemaSet schemas, string uri)
{
var settings = new XmlReaderSettings
{
Schemas = schemas,
ValidationFlags =
XmlSchemaValidationFlags.
ProcessIdentityConstraints |
XmlSchemaValidationFlags.
ReportValidationWarnings,
ValidationType = ValidationType.Schema
};
settings.ValidationEventHandler += OnValidationEventHandler;
using (var validatingReader = XmlReader.Create(uri, settings))
{
XDocument.Load(
validatingReader,
LoadOptions.SetBaseUri | LoadOptions.SetLineInfo);
}
return;
}
这会产生以下结果:
警告:无法找到元素“作业”的架构信息。 警告:找不到元素“作业”的架构信息。 警告:找不到元素“id”的架构信息。 警告:找不到元素“state”的架构信息。 警告:找不到元素“作业”的架构信息。 警告:找不到元素“id”的架构信息。
更改XML并再次运行:
<?xml version="1.0" encoding="utf-8" ?>
<jobs xmlns="http://foo.org/importvalidator.xsd">
<job>
<id>1</id>
<state><![CDATA[IL]]></state>
</job>
<job>
<id>2</id>
</job>
</jobs>
产生您预期的错误:
错误:名称空间“http://foo.org/importvalidator.xsd”中的元素“作业”内容不完整。期望的可能元素列表:名称空间“http://foo.org/importvalidator.xsd”中的“状态”。
答案 2 :(得分:0)
您使用的解析器/语言是什么?过去,如果您使用Java,则必须告诉Xerces解析器您需要XSD验证。但在检查latest release文档后,我发现现在已经内置了验证。所以看起来版本很重要。如果您是.NET开发人员,最好检查其设置是什么。
只是好奇 - 为什么CDATA围绕你的例子中的州?没有必要,AFAIK。您甚至可以在XSD中嵌入限制,以确保只获得有效的美国州代码。
但首先要做的是 - 让模式验证。