gpt4 book ai didi

C# XML 未正确验证 XmlReaderSettings 中的架构

转载 作者:行者123 更新时间:2023-12-04 02:23:56 27 4
gpt4 key购买 nike

我进行了搜索,但没有找到解决此问题的任何问题。

我正在尝试根据模式验证各种 XML,它似乎在验证所有格式良好的 XML,而不仅仅是符合模式的 XML。我已经发布了我正在使用的代码、架构、有效 XML 示例和无效 XML 示例。

我一直在为这个问题苦苦挣扎。我对其中的大部分内容一无所知。我必须学习如何编写 XSD,编写 XSD,然后学习如何在 C# 中解析 XML。这些我以前都没有做过。我使用了许多教程和微软网站来得出以下结论。我认为这应该行得通,但行不通。

我做错了什么?

private bool ValidateXmlAgainstSchema(string sourceXml, string schemaUri)
{
bool validated = false;
try
{
// REF:
// This should create a SCHEMA-VALIDATING XMLREADER
// http://msdn.microsoft.com/en-us/library/w5aahf2a(v=vs.110).aspx

XmlReaderSettings xmlSettings = new XmlReaderSettings();
xmlSettings.Schemas.Add("MySchema.xsd", schemaUri);
xmlSettings.ValidationType = ValidationType.Schema;
xmlSettings.ValidationFlags = XmlSchemaValidationFlags.None;
XmlReader xmlReader = XmlReader.Create(new StringReader(sourceXml), xmlSettings);

// parse the input (not sure this is needed)
while (xmlReader.Read()) ;

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlReader);

validated = true;
}
catch (XmlException e)
{
// load or parse error in the XML
validated = false;
}
catch (XmlSchemaValidationException e)
{
// Validation failure in XML
validated = false;
}
catch (Exception e)
{
validated = false;
}
return validated;
}

XSD/架构。目的是接受包含事件或 PersonOfInterest 的 XML。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="MySchema.xsd"
xmlns="MySchema.xsd"
elementFormDefault="qualified"
>
<xs:element name="Incident" type="IncidentType"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType"/>

<xs:complexType name="IncidentType">
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>

<xs:complexType name="PersonOfInterestType">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>

</xs:schema>

这是有效 XML 的示例

<?xml version="1.0" encoding="utf-8" ?>

<Incident
xmlns="MySchema.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com MySchema.xsd"
>
<Description>something happened</Description>
<PersonOfInterest>
<Name>Joe</Name>
</PersonOfInterest>
<PersonOfInterest>
<Name>Sue</Name>
</PersonOfInterest>
</Incident>

这是一个格式良好的无效 XML 示例,它应该抛出异常(我认为),但是当我尝试它时,代码返回 true,表明它对模式有效。

<ghost>Boo</ghost>

最佳答案

你的原因<ghost>Boo</ghost> validates 是解析器找不到与 xml 匹配的任何模式。如果没有模式,则解析器假设有效,前提是 xml 格式正确。我知道这是违反直觉的,并且可能会根据解析器的实现而有所不同。

尽管如此,您的代码还是有几个问题:

两个根元素

这是 xsd 中的一个大禁忌——你只能有一个根元素。一些解析器实际上会抛出异常,其他解析器容忍它但只会使用第一个根元素(在您的情况下为 Incident)进行任何后续验证。

schemaLocation 属性的使用

这应该取值 (namespace) (URI)其中命名空间是模式的目标命名空间,URI 是模式的位置。在您的情况下,您似乎正在使用架构文件名作为目标命名空间。此外,查看您的代码,您正在将架构加载到您的 xml 阅读器中,因此您实际上根本不需要 schemaLocation 属性。这是一个可选属性,一些解析器完全忽略它。

我建议进行以下更改:

<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://MyMoreMeaningfulNamespace"
xmlns="http://MyMoreMeaningfulNamespace"
elementFormDefault="qualified"
>
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Incident" type="IncidentType"/>
<xs:element maxOccurs="unbounded" name="PersonOfInterest" type="PersonOfInterestType"/>
</xs:sequence>
</xs:complexType>
</xs:element>

<xs:complexType name="IncidentType">
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>

<xs:complexType name="PersonOfInterestType">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>

</xs:schema>

验证这个实例

<Root xmlns="http://MyMoreMeaningfulNamespace">
<Incident>
<Description>something happened</Description>
<PersonOfInterest>
<Name>Joe</Name>
</PersonOfInterest>
<PersonOfInterest>
<Name>Sue</Name>
</PersonOfInterest>
</Incident>

<Incident>
...
</Incident>

<PersonOfInterest>
<Name>Manny</Name>
</PersonOfInterest>

<PersonOfInterest>
...
</PersonOfInterest>

</Root>

关于C# XML 未正确验证 XmlReaderSettings 中的架构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24663939/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com