gpt4 book ai didi

c# - IXmlSerializable 验证模式

转载 作者:数据小太阳 更新时间:2023-10-29 02:57:12 26 4
gpt4 key购买 nike

我正在实现 IXmlSerializable对于我的类的自定义(反)序列化逻辑,但希望根据 XSD 模式检查 XML 的读写。我添加了 XmlSchemaProviderAttribute :

[XmlSchemaProvider("ConfigSchema")]
[XmlRoot("Config")]
public class Config
{
// properties, fields and methods incl. interface methods

public static XmlQualifiedName ConfigSchema(XmlSchemaSet xs)
{
const string xsdPath = "./Config.xsd";

var serializer = new XmlSerializer(typeof(XmlSchema));
var schema = (XmlSchema)serializer.Deserialize(new XmlTextReader(xsdPath), null);

xs.XmlResolver = new XmlUrlResolver();
xs.Add(schema);

return new XmlQualifiedName("Config", "namespace");
}
}

模式加载正常,(反)序列化按预期工作,但没有验证。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ConfigSchema"
targetNamespace="namespace"
elementFormDefault="qualified"
xmlns="namespace"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="Config">
<xs:all>
<xs:element name="Config">
<xs:complexType>
<xs:all>
<xs:element name="name" type="xs:string" />
<xs:element name="timeout" type="xs:time" />
<xs:element name="points" minOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:all>
<xs:element name="a" type="xs:int" />
<xs:element name="b" type="xs:int" />
<xs:element name="c" type="xs:int" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:schema>

如果我根据上述架构反序列化以下内容,则不会引发异常(缺少 <timeout> 但在架构中的 <xs:all> 下指定):

<?xml version="1.0" encoding="utf-8" ?>
<Config
xmlns:xsi="http://w3.org/2001/XMLScehma-instance"
xsi:schemaLocation="namespace Config.xsd">
<name>some name</name>
...

编辑:这是我运行它的方式

string path = "./serviceconfig.xml";
var serializer = new XmlSerializer(typeof(Config));
var cfg = (Config)serializer.Deserialize(new XmlTextReader(path), null);

根据架构验证传入/传出 XML 的“正确”/“最佳”方法是什么?

编辑#2:更多信息

这是完整的 XML

<?xml version="1.0" encoding="utf-8" ?>
<Config
xmlns:xsi="http://w3.org/2001/XMLScehma-instance"
xsi:schemaLocation="namespace Config.xsd">
<name>some name</name>
<timeout>10</timeout>
<points>
<point>
<a>5</a>
<b>7</b>
<c>11</c>
</point>
<point>
<a>8</a>
<b>7</b>
<c>3</c>
</point>
</points>
</Config>

我已经尝试查看 ReadXml(XmlReader reader) 中的 XmlReaderSettings|以下内容没有帮助

var settings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
Schemas = _schemaSet
};

settings.ValidationEventHandler += (sender, args) => Console.WriteLine(args.Message);
reader = XmlReader.Create(reader, settings);

_schema从静态 ConfigSchema() 设置以上。

最佳答案

XML 未通过验证,因为您的模式指定了 targetNamespace = "namespace" 但您的 XML 实例未使用 xmlns 引用此命名空间。

所以验证器不知道如何验证您的 XML,因为它没有意识到您的 XML 使用您的模式中定义的类型。

如果您发布完整的架构和 xml 实例,我将能够制作一个工作示例。

更新

感谢您发布您的架构。你在哪里得到它?我问的原因是它没有定义任何根节点,只是一个名为 Config 的类型。

如果删除外部复杂类型元素:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="ConfigSchema"
targetNamespace="namespace"
elementFormDefault="qualified"
xmlns="namespace"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Config">
<xs:complexType>
<xs:all>
<xs:element name="name" type="xs:string" />
<xs:element name="timeout" type="xs:time" />
<xs:element name="points" minOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="point" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:all>
<xs:element name="a" type="xs:int" />
<xs:element name="b" type="xs:int" />
<xs:element name="c" type="xs:int" />
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>

我能够验证以下实例:

<?xml version="1.0" encoding="utf-8" ?>
<Config xmlns="namespace">
<name>some name</name>
<timeout>13:20:00.000-05:00</timeout>
<points>
<point>
<a>5</a>
<b>7</b>
<c>11</c>
</point>
<point>
<a>8</a>
<b>7</b>
<c>3</c>
</point>
</points>
</Config>

请注意,根据架构,“10”不是超时列的有效值。当我尝试时出现此错误:

The 'namespace:timeout' element is invalid - The value '10' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:time' - The string '10' is not a valid XsdDateTime value.

关于c# - IXmlSerializable 验证模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21284592/

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