在 C# 中针对 XSD 模式验证 json 数据

Posted

技术标签:

【中文标题】在 C# 中针对 XSD 模式验证 json 数据【英文标题】:Validate json data against XSD schema in C# 【发布时间】:2014-07-16 17:11:43 【问题描述】:

我正在做一个项目,我们想根据 xsd 模式验证数据,棘手的部分是数据可能来自同一来源,以 json、xml 等形式出现。我已经弄清楚如何让它针对 xml 进行验证.我无法为 JSON 做同样的事情。我试图避免同时拥有 json 模式和 xml 模式。为此,我将我的 json 文件转换为这样的 XmlDocument;

using (var r = new StreamReader(xmlFileSource))

    var json = r.ReadToEnd();

    var xd = (XmlDocument)JsonConvert.DeserializeXmlNode(
        json.ToString(CultureInfo.InvariantCulture), fileName);

我找不到针对 xsd 文件验证 XmlDocument 的方法。任何帮助将不胜感激,或者如果您有任何建议以更好的方式完成相同的任务。

谢谢!

【问题讨论】:

How to validate an XML document? 的可能重复项 @Edin 不,这不是重复的,OP 正在尝试使用 XML 模式验证 Json。 感谢您的帮助。我正在使用引用的方式来验证 Xml 文档。但似乎无法弄清楚如何使用 Json。如果我错了,请纠正我,但提到的代码处理文件而不是 XmlDocument 类型的对象? @DavidG:你是对的。这让我发布了一个工作示例:) 希望它有所帮助...... Json 和 xml 在延伸到模式验证方面不可互换。 【参考方案1】:

虽然 Mark 更快,但我还是会发布这个,因为它有点不同 - 它不需要再次将 XmlDocument 加载到流中并且它有一个完整的工作示例:

        XmlDocument xml = new XmlDocument();
        xml.LoadXml(@"<?xml version=""1.0"" encoding=""UTF-8""?>
            <shiporder orderid=""889923"">
                <orderperson>John Smith</orderperson>
                <shipto>
                    <name>Ola Nordmann</name>
                    <address>Langgt 23</address>
                    <city>4000 Stavanger</city>
                    <country>Norway</country>
                </shipto>
            </shiporder>");

        xml.Schemas.Add(null, "schema.xsd");
        xml.Validate((sender, args) =>
        
            switch (args.Severity)
            
                case XmlSeverityType.Error:
                    Console.WriteLine("XML is invalid: 0", args.Exception);
                    break;
                case XmlSeverityType.Warning:
                    // handle warning
                    ;
                    break;
            
        );

schema.xsd有以下内容:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="shiporder">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="orderperson" type="xs:string"/>
                <xs:element name="shipto">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="name" type="xs:string"/>
                            <xs:element name="address" type="xs:string"/>
                            <xs:element name="city" type="xs:string"/>
                            <xs:element name="country" type="xs:string"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
            <xs:attribute name="orderid" type="xs:string" use="required"/>
        </xs:complexType>
    </xs:element>
</xs:schema>

您可以通过使您的 xml 无效来测试验证,例如删除元素&lt;orderperson&gt;

显然,您不需要加载 XmlDocument,因为您已经拥有它并且必须调整架构的路径。

【讨论】:

非常感谢您的帮助。完美运行。【参考方案2】:

以accepted answer to a similar question 为基础,并接受这种方法效率低下并可能带来内存使用挑战:

XmlReaderSettings settings = new XmlReaderSettings();

settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add ( .... );  // assumes XSD already available
settings.ValidationEventHandler += delegate( object sender, ValidationEventArgs e )

     DoSomethingAboutSchemaNoncompliance(e.Message);
;

// Get a stream from the XML document for use in schema validation.
XmlReader reader = XmlReader.Create(xd.Save(new System.IO.MemoryStream()), settings);

【讨论】:

以上是关于在 C# 中针对 XSD 模式验证 json 数据的主要内容,如果未能解决你的问题,请参考以下文章

要针对多个 xsd 模式验证 XML

针对同一 XML 模式 (XSD) 加快一批 XML 文件的 XML 模式验证

根据 XML Schema (XSD) 验证 JSON

通过单一方法针对 XSD 验证 XML

针对多个模式定义验证 XML 文件

可以在运行时使用 Objc/iPhone 代码针对 xsd 验证 xml