2011-12-15 2 views
2

다음 코드를 사용하여 XSD 파일에 대해 XML 파일의 유효성을 검사합니다. 오류가 발견되어 XML 파일의 xmlns 값이 유효하면 유효성 검증 처리기를 성공적으로 호출합니다. 유효하지 않으면 유효성 검증 핸들러가 호출되지 않습니다.XmlDocument.Validate가 잘못된 네임 스페이스를 확인하지 않습니다.

private void ui_validate_Click(object sender, EventArgs e) 
{ 
    try 
    { 
     ui_output.Text = ""; 

     XmlDocument xml_document = new XmlDocument(); 
     xml_document.LoadXml(ui_XML.Text); 
     xml_document.Schemas.Add(null, XmlReader.Create(new System.IO.StringReader(ui_XSD.Text))); 
     xml_document.Validate(validation_handler); 
    } 
    catch (Exception ex) 
    { 
     ui_output.Text = "Exception: " + ex.Message; 
    } 
} 

private void validation_handler(object sender, ValidationEventArgs e) 
{ 
    switch (e.Severity) 
    { 
     case XmlSeverityType.Error: 
      ui_output.Text += "Error: " + e.Message + Environment.NewLine; 
      break; 
     case XmlSeverityType.Warning: 
      ui_output.Text += "Warning: " + e.Message + Environment.NewLine; 
      break; 
    } 
} 

업데이트를 허용 대답의 예 :

XmlDocument xml_document = new XmlDocument(); 
xml_document.Load(@"C:\temp\example.xml"); 
xml_document.Schemas.Add(null, @"C:\temp\example.xsd"); 
xml_document.Schemas.Compile(); 

XmlQualifiedName xml_qualified_name = new XmlQualifiedName(xml_document.DocumentElement.LocalName, xml_document.DocumentElement.NamespaceURI); 
bool valid_root = xml_document.Schemas.GlobalElements.Contains(xml_qualified_name); 

답변

4

내가 처리하는 방법은 실제로 문서 요소 (루트 요소)에 XmlSchemaElement가 있는지 확인하는 것입니다. XmlReaderSettings.Schemas; 그렇지 않은 경우 유효성 검사를 실행할 수 없으므로 오류가 발생하지 않습니다.

그래서, 귀하의 XmlSchemaSet is compiled; LocalNameNamespaceUri을 사용하여 XmlQualifiedName을 작성하십시오. 이것을 GlobalElements을 사용하여 XmlSchemaElement을 조회 할 때 사용하십시오.

i) 스키마가 성공적으로 컴파일되고 ii) 실제로 문서의 루트 요소에 대한 정의가있는 경우에만 유효성 검사를 시도해야합니다. 답변에 대한 큰 감사! -

1

를 문서의 루트 요소의 네임 스페이스가 스키마의 대상 네임 스페이스와 일치하지 않는 경우, 유효성 검사기가 없습니다 루트 요소 (또는 대부분의 요소)에 대한 정의가있는 스키마를 찾습니다. 즉, 올바른 구조에 대한 지식이 없기 때문에 유효성 검사기는 잘못된 구조를보고 할 수 없습니다. 이 경우 유효성 검사기는 일반적으로 유효성 검사를 건너 뛰고, 느슨한 유효성 검사 (스키마 정의가있는 요소 만 유효성 검사)를 수행하거나 스키마 정의를 찾지 못하는 것에 대한 경고를 발생시킬 수 있습니다.

빠르게 두 가지 선택 사항이 있다고 생각하십시오. 1) 문서에서 네임 스페이스를 읽고 별도의 체크를 사용하여 옳은지 확인하거나 2) 유효성 검사기의 동작을 변경하여 유효성 검사기의 동작을 변경할 가능성이 있는지 확인합니다. 설정을 사용하여 주어진 네임 스페이스에 대한 정의를 찾지 못했음을 알립니다.

0

@PetruGardea ... 희망이 도움이

난 그냥 다른 사람들이하지 않아도 솔루션을 보여주기 위해 여기에 몇 가지 코드를 넣어

는 구글합니다 :

var doc = new XmlDocument(); 
var set = new XmlSchemaSet(); 

var xsdString = @"<xs:schema 
    xmlns=""http://www.sample.ru/system"" 
    targetNamespace=""http://www.sample.ru/system"" 
    xmlns:xs=""http://www.w3.org/2001/XMLSchema"" 
    elementFormDefault=""qualified""> 

    <xs:element name=""Test""> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name=""B"" > 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 

</xs:schema>"; 

using (var memStream = new MemoryStream()) 
{ 
    var data = Encoding.Default.GetBytes(xsdString); 
    memStream.Write(data, 0, data.Length); 
    memStream.Position = 0; 
    using (var reader = XmlReader.Create(memStream)) 
    { 
     set.Add(@"http://www.sample.ru/system", reader); 
    } 
} 

//doc.LoadXml(@"<a1:Test xmlns:a1=""http://www.sample.ru/system""><a1:B /></a1:Test>"); // valid xml - no errors 
//doc.LoadXml(@"<a1:Test xmlns:a1=""http://www.sample.ru/system""><a1:B1 /></a1:Test>"); // invalid xml - error about B1 
doc.LoadXml(@"<a1:Test xmlns:a1=""http://www.sample.ru/system1""><a1:B1 /></a1:Test>"); // invalid xml with bad namespace - error about namespace 
//doc.LoadXml(@""); // no need to worry that doc.FirstChild is null - in this case this line throws exception 

doc.Schemas.Add(set); 

// !!!! you need to add this code to check for wrong namespace !!!! 
var baseUri = doc.FirstChild.NamespaceURI; 
if (!doc.Schemas.Contains(baseUri)) 
{ 
    Console.WriteLine("Error: there is not xsd to validate this document (uri = {0})", baseUri); 
} 

// the rest of the code just prints validation errors and warnings 
doc.Validate((sender, e) => 
{ 
    Console.WriteLine(e.Message); 
}); 
관련 문제