2013-05-26 9 views
5

XMLを多用し、経験を積み重ねる開発者として、以前はスキーマと実際にやりとりしたことはありません。これは初めて実際に私のために起こっています。XSDでXML文書を正しく検証する

私はよく機能しているバグの多くを考慮した「機能」を実行しました。

XDocument.Validate()を使用すると、指定したスキーマと一致しないドキュメントが有効になることがあります。私はこれがXSD、XML名前空間、および予想される検証プロセス間の関係についての私の理解の欠陥である可能性が最も高いと感じています。

したがって、XMLサンプル、XSDサンプル、および検証コードを送信します。

XML - これは意図的に間違ったドキュメントです。

<?xml version="1.0" encoding="utf-8" ?> 
<SuppliesDefinitions 
    xmlns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Supplies.xsd"> 
    <Supply type="Common"> 
    <Information/> 
    <Ritual/> 
    <Weapon/> 
    <Tool count="1"/> 
    <Tool count="2"/> 
    <Tool count="3"/> 
    </Supply> 
    <Supply type="Uncommon"> 
    <Information/> 
    <Weapon/> 
    <Tool count="1"/> 
    <Tool count="2"/> 
    <Tool count="3"/> 
    <Tool count="4"/> 
    </Supply> 
    <Supply type="Rare"> 
    <Information/> 
    <Rune/> 
    <Weapon/> 
    <Tool count="2"/> 
    <Tool count="3"/> 
    <Tool count="4"/> 
    </Supply> 
</SuppliesDefinitions> 

これを検証するために使用されるXSD。 (これは意図的に上記XMLの意図しない文書です)

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema id="Encounters" 
    targetNamespace="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd" 
    elementFormDefault="qualified" 
    xmlns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd" 
    xmlns:mstns="http://lavendersoftware.org/schemas/SteamGame/Data/Xml/Encounters.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
> 
    <xs:complexType name="ToolType"> 
    <xs:attribute name="count" use="required" type="xs:int"/> 
    </xs:complexType> 

    <xs:complexType name="TaskType"> 
    <xs:choice maxOccurs="unbounded" minOccurs="1"> 
     <xs:element name="Weapon"/> 
     <xs:element name="Information"/> 
     <xs:element name="Tool" type="ToolType"/> 
     <xs:element name="Ritual"/> 
    </xs:choice> 
    </xs:complexType> 


    <xs:complexType name="EncounterType"> 
    <xs:sequence maxOccurs="unbounded" minOccurs="1"> 
     <xs:element name="Task" type="TaskType"/> 
    </xs:sequence> 
    <xs:attribute name="name" use="required" type="xs:string"/> 
    </xs:complexType> 

    <xs:element name="EncounterDefinitions"> 
    <xs:complexType> 
     <xs:sequence maxOccurs="unbounded" minOccurs="1"> 
     <xs:element name="Encounter" type="EncounterType"/> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

最後に検証コードです。

private static void ValidateDocument(XDocument doc) 
    { 
     XmlSchemaSet schemas = new XmlSchemaSet(); 
     schemas.Add(null, XmlReader.Create(new StreamReader(XmlSchemaProvider.GetSchemaStream("Encounters.xsd")))); 

     doc.Validate(schemas, (o, e) => 
     { 
      //This is never hit! 
      Console.WriteLine("{0}", e.Message); 
      Assert.False(e.Severity == XmlSeverityType.Error); 
     }); 
    } 

誰かが私が間違っていることを説明できるかどうか疑問に思っていました。私は、このSHOULDが動作する方法についていくつか誤った仮定をしているように感じています。完全に無関係なXML文書に対してxsdを1つ使用すると無効と思われます。

+0

Xsd検証では、通常、目的のスキーマが見つからない場合にのみ警告が生成されます。あなたはエラーのみをチェックしています。 –

+1

これはここでは当てはまりません。XDocument.Validateの詳細については、http://msdn.microsoft.com/en-us/library/bb354954(v=vs.90).aspxを参照してください。この特定のバリデーションのオーバーロードは、エラーと警告を捕捉します。 –

答えて

3

XMLに、スキーマによって検証できるノードはありません(名前空間は異なります)。結果として、エラーは報告されません。限り、私はすべてのスキーマに一致していないノードの動作を知っている限り何でも許可します。

ReportValidationWarningsを - 検証警告が発生した場合、イベントが報告されるべきであることを示します:

また、警告を許可するようにvalidation options in XmlReaderSettingsを設定することができます。特定の要素または属性を検証するためのDTDまたはXML Schemaが存在しない場合、通常、警告が発行されます。 ValidationEventHandlerは通知に使用されます。

あなたが複数の名前空間からのノードがXMLで存在することが予想される場合XmlSchemaSet.AddHOW TO: Validate an XML Document by Using Multiple Schemasをチェックしてください。

+0

この場合、実際の問題は、ドキュメントルートに指定された名前空間のスキーマと一致するスキーマがXmlSchemaSetスキーマに存在しないことです。実行可能であるべきではないでしょうか? –

+0

@DanielGreenそれはありますが、私はどのように覚えていないのですか...警告を報告するためのリンクを追加しましたので、スキーマを持たない要素について知っておく必要があります。 –

+0

これはすべてうまくできていますが、現在のデザインではXDocumentが採用されていますが、変更しないでください。ストリームを2回読み込むのは間違っているように見えます。 –

関連する問題