2016-05-26 10 views
2

Ich versuche, ein XML mit einem XSD zu validieren. Aber es wirft einen seltsamen Fehler über das Datumsformat:Oracle XML Schema Validierungsdatum Musterfehler

[1]: LSX-00333: wörtliche "2016-05-26T16: 37: 42,000000" ist nicht gültig in Bezug auf das Muster

Allerdings ist es das, was ich in meinem XML haben:

<?xml version="1.0" encoding="UTF-8"?> 
<root DataFeed="2016-04" 
     VersionXSD="2.0" 
     Currency="USD" 
     DataProcessDate="2016-05-26T16:37:42" 
     xmlns="http://www.millicom.com"> 

ich habe dies in meinem XSD:

<xs:attribute name="DataProcessDate" 
       use="required" 
       type="DateTimeType"/> 

<xs:simpleType name="DateTimeType"> 
    <xs:restriction base="xs:dateTime"> 
     <xs:pattern value=".+(\-10:00|\-09:00|\-08:00|\-07:00|\-06:00|\-05:00|\-04:00|\+00:00|Z|-04:00)"/> 
    </xs:restriction> 
</xs:simpleType> 

Und das ist mein Code:

DECLARE 
    v_schema_url VARCHAR2 (200) := 'MyFact.xsd'; 
    v_blob   BLOB; 
    v_clob   CLOB; 
    v_xml   XMLTYPE; 
    xml_file BFILE; 
    xmlClob CLOB; 

    src_offset number := 1 ; 
    dest_offset number := 1 ; 
    lang_ctx number := DBMS_LOB.DEFAULT_LANG_CTX; 
    warning integer; 
    res integer; 
BEGIN 
    dbms_xmlschema.deleteschema(v_schema_url); 
    DBMS_XMLSCHEMA.registerschema (schemaurl => v_schema_url, 
            schemadoc => bfilename ('DIR_XSD','MyFact.xsd'), 
            local  => TRUE); 
    xml_file := BFILENAME('DIR_XSD', 'Test.xml'); 
    DBMS_LOB.CREATETEMPORARY(xmlClob, true); 
    DBMS_LOB.FILEOPEN(xml_file, DBMS_LOB.FILE_READONLY); 
    DBMS_LOB.LOADCLOBFROMFILE(xmlClob, xml_file, DBMS_LOB.LOBMAXSIZE, src_offset, 
          dest_offset, DBMS_LOB.DEFAULT_CSID, lang_ctx, warning); 

    v_xml := XMLType.createXML(xmldata=>xmlClob,schema=>v_schema_url); 

    DBMS_LOB.FILECLOSEALL(); 
    DBMS_LOB.FREETEMPORARY(xmlClob); 

    v_xml.schemaValidate(); 

    IF v_xml.isschemavalid (v_schema_url) = 1 THEN 
     DBMS_OUTPUT.put_line ('valid'); 
    ELSE 
     DBMS_OUTPUT.put_line ('not valid'); 
    END IF; 
END; 

Aus irgendeinem Grund fügt es die Mikrosekunden und es fehlschlägt die Musterprüfung. Wie kann ich das vermeiden? Mein gewünschtes Verhalten ist eine korrekte Ausführung mit einer Ausgabe von "gültig"

+0

Bearbeitet, um zu enthalten, was Sie angegeben haben – Fermin

+0

Ohne die Erklärung Ihres 'DateTimeType' ist es schwer zu sagen, was falsch läuft. –

+0

Es tut mir Leid, dass ich es vergessen habe, und habe es bearbeitet. Obwohl die Antwort, die Arkadiusz Łukasiewicz mir gegeben hat, mir geholfen hat. – Fermin

Antwort

1

Sie machen wahrscheinlich so etwas. Ich nahm an, dass der Datentyp wie folgt deklariert ist.

<xs:simpleType name="DataProcessDateType"> 
    <xs:restriction base="xs:dateTime"> 
     <xs:pattern value="\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}"/> 
    </xs:restriction> 
    </xs:simpleType> 

Und was passiert hier.

  • 1) 2016-05-26T16:37:42 String wird in xs umgewandelt: Datatime und wie 2016-05-26T16:37:42.000000 suchen.

  • 2) Als nächstes wird xsd die Übereinstimmung 2016-05-26T16:37:42.000000 mit dem Muster "\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}" eingeben, aber das Muster hat keine abschließenden Nullen. Und LSX-00333 Fehler wird ausgelöst.

Was Sie tun können.

  • (1- Option) einschließen Nullen in Muster Hinter "\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}"
  • (2 - Option) Entfernen Sie xs: Muster von Typ;

    xsd clob := q'~<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
        <xs:element name="root"> 
        <xs:complexType> 
         <xs:simpleContent> 
         <xs:extension base="xs:string"> 
          <xs:attribute type="xs:string" name="DataFeed"/> 
          <xs:attribute type="xs:float" name="VersionXSD"/> 
          <xs:attribute type="xs:string" name="Currency"/> 
          <xs:attribute type="DataProcessDateType" name="DataProcessDate"/> 
         </xs:extension> 
         </xs:simpleContent> 
        </xs:complexType> 
        </xs:element> 
        <xs:simpleType name="DataProcessDateType"> 
        <xs:restriction base="xs:dateTime"> 
         <xs:pattern value="\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}"/> 
        </xs:restriction> 
        </xs:simpleType> 
    </xs:schema>~'; 
    begin 
        DBMS_XMLSCHEMA.registerschema (schemaurl => 'test_xsd', 
                schemadoc => xmltype(xsd), 
                local  => TRUE); 
    end; 
    

    - exec dbms_XMLSCHEMA.deleteSchema (schemaurl => 'test_xsd'); deklarieren vxml xmltype: = xmltype (q '~~');

    begin 
        vxml := vxml.createschemabasedxml('test_xsd'); 
        vxml.schemaValidate(); 
    IF vxml.isschemavalid ('test_xsd') = 1 THEN 
         DBMS_OUTPUT.put_line ('valid'); 
        ELSE 
         DBMS_OUTPUT.put_line ('not valid'); 
        END IF; 
    end; 
    
1

Obwohl Sie nicht, uns Ihre Datentypdefinition gezeigt haben, ist mein erster Instinkt ist, dass Oracle die Spezifikation falsch interpretieren. Persönlich denke ich, dass die Verwendung von Mustern mit Nicht-String-Datentypen sehr fragwürdig ist, aber die Spezifikation ist ziemlich klar (Teil 2, §4.1.4, Validierungsregel Datentyp Gültig), dass die Musterfacette verwendet werden sollte, um den Wert wie in der Quelldokument (nach Whitespace-Normalisierung), das "ein Literal im lexikalischen Raum" genannt wird, und dieses wird dann in den Wertebereich konvertiert, wo andere Facetten wie minInclusive und Enumeration bewertet werden. Ich habe den Eindruck, dass Oracle stattdessen den lexikalischen Wert genommen, ihn in den Wertebereich konvertiert hat und dann die kanonische lexikalische Form des Wertes gegen das Muster testet. Aber auch das ist nicht richtig, denn die kanonische lexikalische Form kann keine abschließenden Nullen im Bruchteils-Sekunden-Teil enthalten (siehe 3.2.7.2).