简体   繁体   English

C#验证xml

[英]C# Validation xml

I have 2 xsd schemas: 我有2个xsd模式:

A.xsd A.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="myns" xmlns:myns="myns">
  <xs:include schemaLocation="B.xsd"/>
  <xs:element name="A">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="myns:B" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

and B.xsd 和B.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="myns">
  <xs:element name="B" type="xs:string" />
</xs:schema>

And I have 2 xml file: 而且我有2个xml文件:

first 第一

<?xml version='1.0' encoding='utf-8' ?>
<A xmlns='myns'>
  <B xmlns='myns'>sdf</B>
</A>

second 第二

<?xml version='1.0' encoding='utf-8' ?>
<B xmlns='myns'>sdf</B>

I validate xml with this code 我用此代码验证xml

var schemas = new XmlSchemaSet();
schemas.Add("myns", "A.xsd");
xdoc.Validate(schemas, OnValidating);

Both of these xml is valid, but I need that first xml is valid and second not. 这两个xml都是有效的,但是我需要第一个xml是有效的,第二个不是。 How can I do this? 我怎样才能做到这一点?

XSD schemas supplied by a third parties and can not be changed. 第三方提供的XSD模式,不能更改。

The problem you have cannot be solved using your stock validator only. 仅使用库存验证器无法解决您遇到的问题。 The fact that XSD components are spread across different files means nothing to the XSD validator. XSD组件分布在不同文件中的事实对于XSD验证程序没有任何意义。 The idea is that a "Reference to schema components from a schema document is managed in a uniform way, whether the component corresponds to an element information item from the same schema document or is imported" . 该想法是“以统一的方式管理对来自架构文档的架构组件的引用,无论该组件对应于来自同一架构文档的元素信息项还是被导入”

So, without application specific constraints, a document having a root element A vs. another one with a root element B, would validate the same, simply because the processor can find a global element declaration for both. 因此,在没有应用程序特定约束的情况下,具有一个根元素A的文档与具有根元素B的另一个文档的文档将验证该文档,这仅仅是因为处理器可以找到这两个元素的全局元素声明。

What you need to do is create a custom "pre-validation" step based on some configuration information defining the list of allowed root elements. 您需要做的是基于一些配置信息创建一个自定义的“预验证”步骤,该信息定义了允许的根元素列表。 If the document element's qualified name is found in the list, then proceed with the normal validation; 如果在列表中找到文档元素的限定名称,则继续进行常规验证;否则,请继续进行常规验证。 otherwise, fail it right from the beginning. 否则,请从一开始就将其失败。 Probing for the document element's name in a way that doesn't add runtime overhead to your application depends on how your XML is acquired, ie if DOM is involved, or if the readers and/or the underlying stream can seek, etc. 以不增加应用程序运行时间开销的方式探查文档元素的名称取决于获取XML的方式,即是否涉及DOM,或者读者和/或基础流是否可以搜索等。

Regarding the list of allowed elements... if it happens that any of the global elements found in A.xsd is considered by your application as a valid document element in an XML instance document, then you can easily extract the list of allowed root elements qualified names by traversing A.xsd file using .NET's SOM API ; 关于允许的元素列表...如果碰巧A.xsd中找到的任何全局元素被您的应用程序视为XML实例文档中的有效文档元素,那么您可以轻松提取允许的根元素列表通过使用.NET的SOM API遍历A.xsd文件来限定名称; iterate through the XmlSchema.Items looking for XmlSchemaElement types and its QualifiedName property. 遍历XmlSchema.Items以查找XmlSchemaElement类型及其QualifiedName属性。

You could use a dictionary to cache the list of allowed qualified names, or LINQ through the collection, etc. 您可以使用字典来缓存允许的限定名称列表,或者通过集合来缓存LINQ等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM