2009-05-31 11 views
3

Ich habe folgende (errorous) XML:Xsd Validierungsproblem

<jobs> 
    <job> 
     <id>1</id> 
     <state><![CDATA[IL]]></state> 
    </job> 
    <job> 
     <id>2</id> 
    </job> 
</jobs> 

sowohl die ID und die Zustandsknoten Elemente werden reqired. Ich schrieb ein XSD für sie:

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema id="importvalidator" 
    elementFormDefault="qualified" 
    targetNamespace="http://foo.org/importvalidator.xsd" 
    xmlns="http://foo.org/importvalidator.xsd" 
    xmlns:mstns="http://foo.org/importvalidator.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="jobs"> 
     <xs:complexType> 
      <xs:sequence> 
      <xs:element name="job" minOccurs="1" maxOccurs="unbounded"> 
       <xs:complexType> 
       <xs:all> 
        <xs:element name="id" type="xs:string" minOccurs="1"/> 
        <xs:element name="state" type="xs:string" minOccurs="1"/> 
       </xs:all> 
       </xs:complexType> 
      </xs:element> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

Und es bestätigt noch als strukturell gültigen XML-Code. Was fehlt mir hier?

Update1: Der Code, den ich in C#:

 XmlSchemaSet schemas = new XmlSchemaSet(); 
     schemas.Add("http://foo.org/importvalidator.xsd", "validator.xsd"); 

     XDocument doc = XDocument.Load(fileName); 
     if (doc == null | doc.Root == null) 
     { 
      throw new ApplicationException("xml error: the referenced stream is not xml."); 
     } 

     doc.Validate(schemas, (o, e) => 
     { 
      throw new ApplicationException("xsd validation error: xml file has structural problems"); 
     }); 

Antwort

3

Bitte formatieren Sie Ihre xml so ist es einfacher zu lesen - wie folgt aus:

<jobs> 
    <job> 
    <id>1</id> 
    <state><![CDATA[IL]]></state> 
    </job> 
    <job> 
    <id>2</id> 
    </job> 
</jobs> 

Ich glaube, du bist nicht wirklich es Validierung - die Namensräume bedeuten, dass die XML-Validierung nicht, auch mit einem „<state>“ in der zweiten "<job>". Insbesondere hat das XSD einen Zielnamespace von "http://foo.org/importvalidator.xsd" aber das XML hat keinen Namespace angegeben.

Richten Sie einen trivialen Testfall von XSD und XML ein, von dem Sie definitiv wissen, dass er fehlschlägt - verwenden Sie das, um herauszufinden, warum Sie nicht validieren.

Auch Ihre XSD fehlt die enge Tags für Element und das Schema, so sollte es einen Fehler geben - oder es ist nur eine mis-Paste :-)


Sie die Target aus dem Schema entfernen :

<xs:schema id="importvalidator" 
    elementFormDefault="qualified" 
    targetNamespace="http://foo.org/importvalidator.xsd ← DELETE THIS" 
    xmlns="http://foo.org/importvalidator.xsd" 
    xmlns:mstns="http://foo.org/importvalidator.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

wie folgt So sieht es aus:

<xs:schema id="importvalidator" 
    elementFormDefault="qualified" 
    xmlns="http://foo.org/importvalidator.xsd" 
    xmlns:mstns="http://foo.org/importvalidator.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

PS: Wer weiß, ob/wie kann man hoch Licht Teile des Quellcodes mit SO Markdown?

+2

@ 13ren: Ich habe seine Formatierung korrigiert, damit die Close-Tags sichtbar sind. Sie haben die richtige Antwort: Es wird nicht wegen des Namensraums überprüft. –

+0

@ 13ren: mit einem ungarischen Tastaturlayout + Google Chrome, bin ich glücklich, wenn ich nur Code-Blöcke einfügen kann ...:/ – balint

+0

@ 13ren, @John: OK, aber wie kann ich eine Validierung ohne Namespace-Deklaration machen ? – balint

0

Welche Parser/Sprache verwenden Sie? Früher mussten Sie dem Xerces-Parser mitteilen, dass Sie eine XSD-Validierung wünschen, wenn Sie Java verwenden. Aber nachdem ich die latest release Dokumente überprüft habe, sehe ich, dass die Validierung jetzt eingebaut ist. Es scheint also, dass die Version wichtig ist. Wenn Sie ein .NET-Entwickler sind, überprüfen Sie am besten, was seine Einstellungen sein müssen.

Nur neugierig - warum die CDATA den Zustand in Ihrem Beispiel umgibt? Das ist nicht nötig, AFAIK. Sie können sogar eine Einschränkung in Ihr XSD einbetten, um sicherzustellen, dass Sie nur gültige US-Bundesstaatencodes erhalten.

Aber zuerst die Dinge zuerst - das Schema validieren.

+0

@duffymo: danke für deinen Kommentar, 1) es ist ein .net-Projekt in C#. 2) Ich weiß, aber ich kann die Struktur des Xml nicht ändern, BTW die State-Code-Validierung ist (noch) nicht im Rahmen des Projekts. – balint

+0

Sie sind herzlich willkommen, Balint. Es tut mir leid, dass ich nicht hilfsbereiter bin. Ich würde nicht in Betracht ziehen, eine unnötige CDATA als modifizierende Struktur zu entfernen, aber vielleicht kenne ich nicht alle Ihre Anforderungen. Es ist gut, über die staatliche Validierung nachzudenken, wenn es wichtig wird, aber vielleicht ist dieser Tag heute nicht. – duffymo

2

@ 13ren hat die richtige Antwort. Es ist kein Fehler, wenn ein Knoten keinem Schema entspricht. Es ist nur eine Warnung. Ich kann die Warnungen im Code unten:

private static void ValidateDocument(XmlSchemaSet schemas, string uri) 
{ 
    var settings = new XmlReaderSettings 
         { 
          Schemas = schemas, 
          ValidationFlags = 
           XmlSchemaValidationFlags. 
            ProcessIdentityConstraints | 
           XmlSchemaValidationFlags. 
            ReportValidationWarnings, 
          ValidationType = ValidationType.Schema 
         }; 
    settings.ValidationEventHandler += OnValidationEventHandler; 
    using (var validatingReader = XmlReader.Create(uri, settings)) 
    { 
     XDocument.Load(
      validatingReader, 
      LoadOptions.SetBaseUri | LoadOptions.SetLineInfo); 
    } 
    return; 
} 

Daraus ergibt sich die folgende:

Warnung: Konnte nicht Schemainformationen für das Element ‚Jobs‘ gefunden. Warnung: Schemainformationen für das Element 'job' konnten nicht gefunden werden. Warnung: Schemainformationen für das Element 'ID' konnten nicht gefunden werden. Warnung: Schemainformationen für das Element 'state' konnten nicht gefunden werden. Warnung: Schemainformationen für das Element 'job' konnten nicht gefunden werden. Warnung: Schemainformationen für das Element 'ID' konnten nicht gefunden werden.

Ändern der XML und läuft wieder:

<?xml version="1.0" encoding="utf-8" ?> 
<jobs xmlns="http://foo.org/importvalidator.xsd"> 
    <job> 
    <id>1</id> 
    <state><![CDATA[IL]]></state> 
    </job> 
    <job> 
    <id>2</id> 
    </job> 
</jobs> 

erzeugt den Fehler, den Sie erwartet:

Fehler: Das Element 'Job' im Namensraum 'http://foo.org/importvalidator.xsd' hat unvollständige Inhalte. Liste der möglichen erwarteten Elemente: 'state' im Namensraum 'http://foo.org/importvalidator.xsd'.

+0

John, danke für deine Antwort! Ich war auf der Suche nach einem guten Beispiel für die Validierung mit XDocument, das war alles, was ich kann :) Ich kann nicht mit Xsd validieren, ohne einen Namespace in der Xml-Datei zu setzen? (Es ist ein riesiges xml in der Größe, und ich habe Angst, wenn ich die Struktur ändere, wird es einen Einfluss auf die Ladegeschwindigkeit haben). – balint

+0

Ich denke, du verpasst meinen Punkt. Wenn Ihr XML-Code ohne Namespace gültig ist, ist Ihr Schema falsch. Wenn Ihr Schema richtig ist, ist Ihr XML ohne einen Namespace nicht gültig. –