0

MonoでC#を使用していますが、XPathNavigatorを使用してXMLスキーマで検証されたXmlDocumentをナビゲートしたいと思います。重要なのは、ドキュメントをトラバースするときに、XPathNavigator.SchemaInfoプロパティを介して各要素のXMLスキーマ情報を取得できることです。ただし、XPathNavigator.MoveToFirstChild()を呼び出した後、XPathNavigator.SchemaInfo=nullになります。これが例です

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であり、デバッグとリリースで発生します。

更新私はちょうどこれを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 . . .

それで多分モノのこと?

4

1 に答える 1

0

バグを報告することになりました-https://bugzilla.xamarin.com/show_bug.cgi?id= 9541

XmlSchemaSetのルートXmlSchemaElementからトラバースし、XmlQualifiedNameによってすべてのXmlSchemaElementsとXmlSchemaAttributesを記録し、次にXPathNavigatorによってXmlDocumentをトラバースするときに、XPathNavigatorからXmlQualifiedNameを使用してXmlSchemaElement/XmlSchemaAttributeを検索することで問題を回避しています。それはちょっと機能しますが、XmlQualifiedNameがスキーマ内の要素のインスタンスを一意に識別するのに十分ではないため、機能しません。たとえば、要素は、異なるmaxOccurs/minOccurs値を持つスキーマのさまざまな場所で使用できます。

于 2013-01-24T09:43:35.477 に答える