首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于模式的IXmlSerializable验证

基于模式的IXmlSerializable验证
EN

Stack Overflow用户
提问于 2014-01-22 13:43:38
回答 2查看 547关注 0票数 2

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

代码语言:javascript
复制
[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");
    }
}

模式按预期的方式加载精细和(反)序列化,但没有验证。

代码语言:javascript
复制
<?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>中指定):

代码语言:javascript
复制
<?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>
        ...

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

代码语言:javascript
复制
string path = "./serviceconfig.xml";
var serializer = new XmlSerializer(typeof(Config));
var cfg = (Config)serializer.Deserialize(new XmlTextReader(path), null);

什么‘正确’/‘最好’的方式,以验证不开始/输出XML的模式?

编辑#2:更多信息

这是完整的XML

代码语言:javascript
复制
<?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>

我试着用下面的方法研究XmlReaderSettings中的ReadXml(XmlReader reader),但这并没有帮助

代码语言:javascript
复制
var settings = new XmlReaderSettings
{
    ValidationType = ValidationType.Schema,
    Schemas = _schemaSet
};

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

_schema是从上面的静态ConfigSchema()设置的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-22 18:24:01

经过很长时间的挖掘,在休回答的帮助下,我终于解决了这个难题。

  1. 我将命名空间添加到XML和C#类中: XmlSchemaProvider("ConfigSchema")公共类Config : IXmlSerializable {私有静态XmlSchemaSet _schema;公共静态XmlQualifiedName ConfigSchema(XmlSchemaSet xs) { _schema = xs;//方法的其他形式为OP } public void ReadXml(XmlReader reader) { var设置=新XmlReaderSettings { ValidationType = ValidationType.Schema,Schema= _schemas;reader.Read();//您自己的读取逻辑} //类的其余部分}
  2. 我的XSD全错了。我混淆了类型定义和元素结构定义。
票数 1
EN

Stack Overflow用户

发布于 2014-01-22 14:51:39

因为您的架构指定了一个targetNamespace = "namespace",但是您的XML实例没有使用xmlns引用这个命名空间,所以XML没有进行验证。

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

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

更新

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

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

代码语言:javascript
复制
<?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>

我能够验证以下实例:

代码语言:javascript
复制
<?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“不是超时值列的有效值。当我尝试时,我得到了这个错误:

“名称空间:超时值”元素无效--根据其数据类型'http://www.w3.org/2001/XMLSchema:time‘,值'10’无效--字符串'10‘不是有效的XsdDateTime值。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21284592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档