2013-01-11 25 views
0

我正在使用C#和Mono,并且我想使用XPathNavigator导航XML模式验证的XmlDocument。当我遍历文档时,我可以通过XPathNavigator.SchemaInfo属性获取每个元素的XML SChema信息。但是,在我调用XPathNavigator.MoveToFirstChild()之后,XPathNavigator.SchemaInfo = null。下面是一个例子XPathNavigator.SchemaInfo在Mono中导航后为空

using System; 

using System.IO; 
using System.Xml; 
using System.Xml.XPath; 
using System.Xml.Schema; 

namespace XmlSchemaTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      XmlDocument xmlDocument = ReadAndValidateXmlFile(@"../test.xml", @"../test.xsd"); 

      if (xmlDocument == null) 
       Console.WriteLine("Cannot open document or it didn't validate."); 
      else 
      { 
       XPathNavigator xpathNavigator = xmlDocument.CreateNavigator(); 
       Console.WriteLine("XPathNavigator.SchemaInfo is " + ((xpathNavigator.SchemaInfo == null) ? "null" : "not null")); 

       xpathNavigator.MoveToRoot(); 
       Console.WriteLine("Called XPathNavigator.MoveToRoot()"); 

       if(xpathNavigator.MoveToFirstChild()) 
       { 
        Console.WriteLine("XPathNavigator.LocalName after .MoveToFirstChild() succeeded = " + xpathNavigator.LocalName); 
        Console.WriteLine("XPathNavigator.NodeType value = " + xpathNavigator.NodeType.ToString()); 
        Console.WriteLine("XPathNavigator.SchemaInfo is " + ((xpathNavigator.SchemaInfo == null) ? "null" : "not null")); 
       } 
      } 

      //Console.ReadLine(); 
     } 

     private static XmlDocument ReadAndValidateXmlFile(string xmlPath, string xsdPath) 
     { 
      // Load the XML Schema 
      bool anyValidationErrors = false; 
      XmlSchemaSet oSchemaSet = new XmlSchemaSet(); 
      ValidationEventHandler Handler = new ValidationEventHandler((object sender, ValidationEventArgs args) => {Console.WriteLine(args.Message); anyValidationErrors = true;}); 
      oSchemaSet.ValidationEventHandler += Handler; 
      XmlSchema oSchema = null; 
      using (StreamReader sr = new StreamReader(xsdPath)) { 
       oSchema = XmlSchema.Read(sr, Handler); 
      } 
      if (anyValidationErrors || (oSchema == null)) { 
       Console.WriteLine("Schema validation errors"); 
       return null;  
      } 
      oSchemaSet.Add(oSchema); 

      // Set up the Xml reader to do schema validation 
      XmlReaderSettings xmlReaderSettings = new XmlReaderSettings(); 
      xmlReaderSettings.ValidationType = ValidationType.Schema; 
      xmlReaderSettings.Schemas.Add(oSchemaSet); 
      anyValidationErrors = false; 
      xmlReaderSettings.ValidationEventHandler += new ValidationEventHandler((object sender, ValidationEventArgs args) => {Console.WriteLine(args.Message); anyValidationErrors = true;}); 

      // Load the Xml and validate against schemer 
      using (XmlReader xmlReader = XmlReader.Create(xmlPath, xmlReaderSettings)) 
      { 
       XmlDocument xmlDocument = new XmlDocument(); 
       xmlDocument.Load(xmlReader); 

       if (anyValidationErrors) { 
        Console.WriteLine("Xml validation errors"); 
        return null; 
       } 
       else 
        return xmlDocument; 
      } 
     } 
    } 
} 

有了这个XSD

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema id="TEST" 
      targetNamespace="urn:test" 
      xmlns:tst="urn:test" 
      xmlns="urn:test" 
      elementFormDefault="qualified" 
      xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="TestElement"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="SubEle"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="ChildEle" type="xs:unsignedInt" /> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

而这个XML

<?xml version="1.0" encoding="utf-8" ?> 
<tst:TestElement xmlns:tst="urn:test"> 
    <tst:SubEle> 
    <tst:ChildEle>123</tst:ChildEle> 
    </tst:SubEle> 
</tst:TestElement> 

给出了这样的输出

XPathNavigator.SchemaInfo is not null 
Called XPathNavigator.MoveToRoot() 
XPathNavigator.LocalName after .MoveToFirstChild() succeeded = TestElement 
XPathNavigator.NodeType value = Element 
XPathNavigator.SchemaInfo is null 

任何一个有建议,是怎么回事或者我做错了什么?

感谢 戴夫

PS我说的“单声道”,因为这是我在用,我没能还上的Windows确认。另外,它的运行时版本是.Net 4.0,发生在Debug和Release中。

UPDATE我只是想在Windows操作系统上,得到了这样的结果

XPathNavigator.SchemaInfo is not null 
Called XPathNavigator.MoveToRoot() 
XPathNavigator.LocalName after .MoveToFirstChild() succeeded = TestElement 
XPathNavigator.NodeType value = Element 
XPathNavigator.SchemaInfo is not null 
Press any key to continue . . . 

所以,也许一个单声道的事情吗?

+0

什么版本的Mono? – knocte

+0

单声道JIT编译器版本2.10.5(Debian 2.10.5-1ubuntu0.1) 版权所有(C)2002-2011 Novell,Inc,Xamarin,Inc和贡献者。 www.mono-project.com \t TLS:__thread \t SIGSEGV:altstack \t声明:epoll的 \t硬件架构: \t禁用:无 \t其他:softdebug \t LLVM:支持,尚未启用。 \t GC:包括Boehm(带键入的GC和并行标记) 在Ubuntu 11.10 – Dave

+1

如果它在Windows(使用MS.NET,而不是Mono)中工作并且它不在Mono上,那么:首先,将您的Mono更新为3.x,再次测试,如果它仍然不起作用,那么在这里提交一个最小的测试用例:http://bugzilla.xamarin.com/ – knocte

回答

0

我最终提交错误 - https://bugzilla.xamarin.com/show_bug.cgi?id=9541

我工作围绕这一问题通过从XmlSchemaSet中根XmlSchemaElement遍历和XmlQualifiedName记录所有XmlSchemaElements和XmlSchemaAttributes,然后遍历由XPathNavigator的XmlDocument的时候,使用XPathNavigator中的XmlQualifiedName来查找XmlSchemaElement/XmlSchemaAttribute。它有点作品,但也不是因为XmlQualifiedName不足以唯一标识模式中的元素isntance,例如一个元素可以在具有不同maxOccurs/minOccurs值的架构中的不同位置使用。