使用 XSD 验证 XmlDocument

发布于 2024-09-11 04:59:50 字数 2398 浏览 3 评论 0原文

我正在开发一个系统,它将通过 Web 服务接收 XML (XmlDocument)。我不会在硬盘上保存此 XML (XmlDocument)。它将在内存上进行管理。

我有一个文件 XSD 来验证从 WebService 收到的 XML (XmlDocument)。我正在尝试做一个示例来说明如何验证此 Xml。

我的 XML:

<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

我也有我的 XSD:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
  <xs:element name="note">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="to" type="xs:string"/>
        <xs:element name="from" type="xs:string"/>
        <xs:element name="heading" type="xs:string"/>
        <xs:element name="body" type="xs:int"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

正如我们所看到的,我将 body 字段设置为 int,只是为了模拟错误。

好吧,为了尝试得到错误,我有以下代码:

//event handler to manage the errors
private static void verifyErrors(object sender, ValidationEventArgs args)
{
    if (args.Severity == XmlSeverityType.Warning)
        MessageBox.Show(args.Message);
}

在单击按钮上,我有:

        private void button1_Click(object sender, EventArgs e)
        {

            try
            {
                // my XmlDocument (in this case I will load from hardisk)
                XmlDocument xml = new XmlDocument();
                // load the XSD schema.. is this right?
                xml.Schemas.Add("http://www.w3schools.com", "meuEsquema.xsd");

                // Load my XML from hardisk
                xml.Load("meusDados.xml");

                // event handler to manage the errors from XmlDocument object
                ValidationEventHandler veh = new ValidationEventHandler(verificaErros);

                // try to validate my XML.. and the event handler verifyError will show the error
                xml.Validate(veh);
            }
            catch {
              // do nothing.. just to test
            }
        }

问题是我将 body 字段更改为 int,但有该字段中的字符串值,我没有收到错误。

I am developing a system that will receive a XML (XmlDocument) via webservice. I won't have this XML (XmlDocument) on hardisk. It will be managed on memory.

I have a file XSD to validate the XML (XmlDocument) that I receive from my WebService. I am trying to do a example to how validate this Xml.

My XML:

<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

also I have my XSD:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
  <xs:element name="note">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="to" type="xs:string"/>
        <xs:element name="from" type="xs:string"/>
        <xs:element name="heading" type="xs:string"/>
        <xs:element name="body" type="xs:int"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

As we can see, the body field I've put as int, just to simulate the error.

Well, to try get the error, I have the following code:

//event handler to manage the errors
private static void verifyErrors(object sender, ValidationEventArgs args)
{
    if (args.Severity == XmlSeverityType.Warning)
        MessageBox.Show(args.Message);
}

On click button, I have:

        private void button1_Click(object sender, EventArgs e)
        {

            try
            {
                // my XmlDocument (in this case I will load from hardisk)
                XmlDocument xml = new XmlDocument();
                // load the XSD schema.. is this right?
                xml.Schemas.Add("http://www.w3schools.com", "meuEsquema.xsd");

                // Load my XML from hardisk
                xml.Load("meusDados.xml");

                // event handler to manage the errors from XmlDocument object
                ValidationEventHandler veh = new ValidationEventHandler(verificaErros);

                // try to validate my XML.. and the event handler verifyError will show the error
                xml.Validate(veh);
            }
            catch {
              // do nothing.. just to test
            }
        }

The problem is that I changed the body field to int, but there are a string value in that field and I am not getting error.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

转瞬即逝 2024-09-18 04:59:50

问题在于 XML 命名空间。

在 XSD 中,您将 targetNamespace=xmlns= 定义为 "http://www.w3schools.com"

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3schools.com"
           xmlns="http://www.w3schools.com"
           elementFormDefault="qualified">

但是 -您的 XML 文档包含任何 XML 命名空间。

<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

所以基本上,XSD 根本不验证此 XML。

您需要从 XSD 中删除这些命名空间:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">

或者将 XSD 中定义的默认 XML 命名空间(无前缀)添加到 XML:

<?xml version="1.0"?>
<note xmlns="http://www.w3schools.com">
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

如果您的 XSD 中有 XML 命名空间,则这些命名空间必须在 XML 中显示为好吧 - 反之亦然。

一旦您执行了一种或另一种解决方案,您应该会收到类似以下内容的验证错误:

Validation error: The 'body' element is invalid - The value 'Don't forget me this weekend!' is invalid according to its datatype
'http://www.w3.org/2001/XMLSchema:int' - The string 'Don't forget me this weekend!' is not a valid Int32 value.

The problem is XML namespaces.

In your XSD, you define the targetNamespace= and xmlns= to both be "http://www.w3schools.com":

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.w3schools.com"
           xmlns="http://www.w3schools.com"
           elementFormDefault="qualified">

However - your XML document does not contain any XML namespaces.

<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

So basically, that XSD isn't validating this XML at all.

You need to either remove those namespaces from your XSD:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified">

or alternatively, add the default XML namespace (with no prefix) defined in your XSD to your XML:

<?xml version="1.0"?>
<note xmlns="http://www.w3schools.com">
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

If you have XML namespaces in your XSD, those have to be present in the XML as well - and vice versa.

Once you do one or the other solution, you should get a validation error something like:

Validation error: The 'body' element is invalid - The value 'Don't forget me this weekend!' is invalid according to its datatype
'http://www.w3.org/2001/XMLSchema:int' - The string 'Don't forget me this weekend!' is not a valid Int32 value.
醉态萌生 2024-09-18 04:59:50

我希望我能在这里帮助你。 我有类似的问题(带有 Xml 误报)。

我在我的特定情况下发现了两个错误,其中一个可能实际上是相关的。您必须通过 XmlReaderSettings 选择加入各种 Xml 验证。这是一个简单的用法(摘自上面的帖子)

string schemaFileName = @"sampleSchema.xsd"; 
string xmlFileName = @"sampleXml.xml"; 
XmlReaderSettings settings = new XmlReaderSettings 
{ 
    ValidationType = ValidationType.Schema, 
    ValidationFlags =  
        XmlSchemaValidationFlags.ProcessInlineSchema | 
        XmlSchemaValidationFlags.ProcessSchemaLocation |  
        XmlSchemaValidationFlags.ReportValidationWarnings, 
}; 
settings.Schemas.Add (schema); 
settings.ValidationEventHandler +=  
    (o, e) => { throw new Exception("CRASH"); }; 

XmlSchema schema =  
    XmlSchema.Read ( 
    File.OpenText (schemaFileName),  
    (o, e) => { throw new Exception ("BOOM"); }); 

// obviously you don't need to read Xml from file, 
// just skip the load bit and supply raw DOM object
XmlReader reader = XmlReader.Create (xmlFileName, settings); 
while (reader.Read ()) { } 

I am hoping I can help you here. I had a similar issue (with Xml false-positives).

I found two errors in my particular situation, one which may actually be relevant. You must opt-in to various Xml validation via XmlReaderSettings. Here is a simple usage (taken from post above)

string schemaFileName = @"sampleSchema.xsd"; 
string xmlFileName = @"sampleXml.xml"; 
XmlReaderSettings settings = new XmlReaderSettings 
{ 
    ValidationType = ValidationType.Schema, 
    ValidationFlags =  
        XmlSchemaValidationFlags.ProcessInlineSchema | 
        XmlSchemaValidationFlags.ProcessSchemaLocation |  
        XmlSchemaValidationFlags.ReportValidationWarnings, 
}; 
settings.Schemas.Add (schema); 
settings.ValidationEventHandler +=  
    (o, e) => { throw new Exception("CRASH"); }; 

XmlSchema schema =  
    XmlSchema.Read ( 
    File.OpenText (schemaFileName),  
    (o, e) => { throw new Exception ("BOOM"); }); 

// obviously you don't need to read Xml from file, 
// just skip the load bit and supply raw DOM object
XmlReader reader = XmlReader.Create (xmlFileName, settings); 
while (reader.Read ()) { } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文