【问题标题】:Validating XmlDocument with a XSD使用 XSD 验证 XmlDocument
【发布时间】:2010-07-21 20:23:42
【问题描述】:

我正在开发一个系统,该系统将通过 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,但该字段中有一个字符串值,我没有收到错误。

【问题讨论】:

    标签: xml validation xmldocument


    【解决方案1】:

    问题在于 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.
    

    【讨论】:

    • 嗨,Marc,我尝试放置命名空间,但没有成功。我的命名空间:w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="./Schema.xsd"> 我做错了什么?
    • @Dan:使用我在回复中发布的版本:&lt;note xmlns="http://www.w3schools.com"&gt;
    • 嗨@mar​​c_s。你能用 10 美元的 paypal 帮我解决这个问题吗?我真的没有得到错误。我知道你是自愿来的,但我是 C# 的新程序员,我还在研究 XML。最好的,丹
    • @Dan:给我发一封电子邮件 - 查看我的个人资料 - 我会尝试通过电子邮件提供帮助,可能比这里更容易和更有效率。
    【解决方案2】:

    我希望我能在这里为您提供帮助。 I had a similar issue(带有 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 ()) { } 
    

    【讨论】:

    • 这不会解决真正的问题 - XSD 中定义的 XML 命名空间,但 XML 中不存在......
    猜你喜欢
    • 2012-12-13
    • 2015-07-29
    • 2011-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多