2012-11-04 2 views
7

Vorrei fare una domanda sulla convalida del documento XML rispetto ai suoi schemi XML corrispondenti e sarei grato se potessi gentilmente darmi una mano. In realtà, ho appena iniziato a conoscere gli schemi XML (sono totalmente un principiante). Ho acquistato il libro "Definitive XML Schema" scritto da Priscilla Walmsley (2a edizione) che presenta XML Schema 1.1 (che credo sia la versione più recente).Oracle può convalidare XML utilizzando uno schema XSD sul file system locale?

Ora il problema è che in tutti gli esempi e gli esercizi del libro, gli spazi dei nomi e la posizione dei file dello schema vengono forniti utilizzando un URL web.

Ecco un esempio del libro:

Questo è lo schema

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://datypic.com/prod" 
      xmlns:prod="http://datypic.com/prod"> 

    <xs:element name="product" type="prod:ProductType"/> 
    <xs:complexType name="ProductType"> 
     <xs:sequence> 
      <xs:element name="number" type="xs:integer"/> 
      <xs:element name="size" type="prod:SizeType"/> 
     </xs:sequence> 
     <xs:attribute name="effDate" type="xs:date"/> 
    </xs:complexType> 
    <xs:simpleType name="SizeType"> 
     <xs:restriction base="xs:integer"> 
      <xs:minInclusive value="2"/> 
      <xs:maxInclusive value="18"/> 
     </xs:restriction> 
    </xs:simpleType> 
</xs:schema> 

E il contenuto XML per essere convalidati in base al sopra citato è presente

<prod:product xmlns:prod="http://datypic.com/prod" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://datypic.com/prod prod.xsd" 
      effDate="2011-04-12"> 
    <number>557</number> 
    <size>10</size> 
</prod:product> 

Ovviamente, [ http://datypic.com/prod] è un sito gestito dall'autore, quindi non posso aggiungere o CANCELLARE alcun file su questo sito per i miei esercizi mentre sto leggendo questo libro. Di conseguenza ho bisogno di mettere entrambi i documenti XML e XSD sul mio disco rigido locale (sto usando Linux Fedora Core 17 X86_64). Quindi, ciò che ho fatto è stato inserire il contenuto dello schema in un file chiamato per esempio 'Esempio-01.xsd' e il contenuto XML in un file denominato 'Esempio-01.xml'.

Uso il pacchetto oracle PL/SQL DBMS_XMLSCHEMA (Enterprise Edition 11.2.0.1.0) per registrare prima lo schema e quindi chiamare il metodo di convalida dell'oggetto XMLType per convalidare il mio documento XML rispetto allo schema, simile a il seguente link:

https://forums.oracle.com/forums/thread.jspa?messageID=2462207

ho creato una directory (per creare la directory) dichiarazione in Oracle:

/home/treno/Documents/myutl_file_dir/

Dove ho inserito entrambi i miei documenti XML & XSD. Ecco esattamente come ho cambiato il contenuto XML di cui sopra, al fine di fare riferimento a XSD localmente

<prod:product xmlns:prod="http://datypic.com/prod" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://datypic.com/prod file:///home/train/Documents/myutl_file_dir/Example-01.xsd" 
       effDate="2011-04-12"> 
    <number>557</number> 
    <size>10</size> 
</prod:product> 

Quindi, se si confronta il nuovo contenuto XML con l'esempio di cui sopra, l'unica cosa che ho aggiunto era file:///home/train/Documents/myutl_file_dir/Example-01.xsd alla fine del valore di xsi: schemaLocation per fare riferimento al disco rigido locale. Ho trovato questo metodo, qui:

http://lists.w3.org/Archives/Public/xmlschema-dev/2001Dec/0161.html

Ora, il problema è che non funziona. Quando eseguo il mio script per validare il documento chiamando il metodo schemaValidate() dell'oggetto XMLType, ecco il messaggio di errore Oracle:

BEGIN 
* 
ERROR at line 1: 
ORA-19030: Method invalid for non-schema based XML Documents. 
ORA-06512: at "SYS.XMLTYPE", line 354 
ORA-06512: at "TRAIN2012.ZXML_PKG", line 176 
ORA-06512: at line 2 

Quello che ho capito dal messaggio di errore 'Metodo non valido per non Documenti XML basati sullo schema ' è che oracle ha semplicemente ignorato il percorso file che ho definito per il file dello schema e ritiene che non ci sia stato alcun schema dichiarato per questo documento XML.

Qualche idea? Come posso affrontare questo problema?

Grazie in anticipo,

Dariyoosh

risposta

7

OK, dopo un sacco di usare Google e grazie Stefan nebesnak' commento che ho trovato due problemi che ha causato l'errore:

Il primo, come menzionato Stefan, è che DBMS_XMLSCHEMA.registerSchema può essere applicato solo al documento basato sullo schema. Inizialmente ciò che avevo fatto nel mio codice PL/SQL era qualcosa di simile:

Quindi, come potete vedere non v'è assolutamente alcun legame tra lo schema registrato e l'oggetto XMLType che si riferisce al mio documento XML. Quello che ho dovuto fare è stato questo:

l_xml_file_content := 
    XMLType(
      'Here I put the content of my XML document' 
     ).createSchemaBasedXML('and here I put the very same schema URL used during registereation while I registered the schema by calling the DBMS_XMLSCHEMA.registerSchema method') 

Così, il primo problema è stato risolto e il mio documento XML è diventato uno schema-base.

Il secondo problema è stato il fatto che nel libro documento XML da convalidare in base allo schema era stato definito nel seguente modo:

<prod:product xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:prod="http://datypic.com/prod" 
       xsi:schemaLocation="http://datypic.com/prod prod.xsd" 
       effDate="2011-04-12"> 

    <number>557</number> 
    <size>10</size> 
</prod:product> 

Quello che ho capito da 'xsi: schemaLocation = "http: //datypic.com/prod prod.xsd "" è che la prima parte di esso, ovvero http://datypic.com/prod fa riferimento a targetNameSpace e la seconda parte è separata da uno spazio, ovvero , prod.xsd, viene utilizzato per fare riferimento alla posizione (come URL) del documento dello schema che è true . Ma quello che non sapevo era che nell'oracle DBMS_XMLSCHEMA di implementazione, questa seconda parte deve essere la stessa URL utilizzata per registrare lo schema chiamando il metodo DBMS_XMLSCHEMA.RegisterSchema, altrimenti non funzionerà. Ed ecco il link alla documentazione oracolo che lo conferma:

http://docs.oracle.com/cd/B19306_01/appdev.102/b14259/xdb03usg.htm#BABBGBDA

If the target XML schema declares a target namespace, then the schemaLocation attribute is used to identify the XML schema. The value of this attribute is a pair of values separated by a space:

  • the value of the target namespace declared in the XML schema
  • the schema location hint, the unique identifier passed to procedure DBMS_XMLSCHEMA.registerSchema when the schema is registered with the database

E questo era proprio quello che non avevo fatto, avevo registrato lo schema con 'http: // datypic. it/prod 'e solo perché nel libro c'era un nome di file come seconda parte di xsi: schemaLocation (prod.xsd) Ho pensato che tutto ciò che dovevo fare era mettere il contenuto dello schema in un file chiamato ad esempio Esempio-01.xsd e quindi fornire l'URL del file a questo documento, file: /// home/treno/Documenti/myutl_file_dir /Example-01.xsd. Il che è davvero una cosa sciocca perché, quando registri uno schema con Oracle chiamando il DBMS_XMLSchema.registerSchema, oracle registra il contenuto del documento dello schema XML. Quindi ciò di cui ha bisogno oracle è lo schemaURL utilizzato durante la registrazione che consente di trovare e identificare in modo univoco lo schema specifico. E questo era esattamente il mio errore, avevo pensato che oracle cercasse la posizione fisica del mio file.

Conclusione: aveva registrato lo schema dal targetNamespace: 'http://datypic.com/prod' (beh, era solo un esempio, ho potuto scegliere altro valore)

Quindi, la corretta valore di schemaLocation all'interno del mio documento XML era questo:

xsi:schemaLocation="http://datypic.com/prod prod.xsd 
        http://datypic.com/prod prod.xsd" 

E questo ha risolto il problema.

Spero che questo possa aiutare coloro che hanno riscontrato lo stesso problema.

saluti,

Dariyoosh

0

Il metodo può essere invocato solo su oggetti XmlType schema base.

Provare a eliminare e ricaricare i documenti, prima di registrare uno schema XML a cui si riferiscono.

Oracle XML DB Developer's Guide:

When you register an XML schema, keep in mind that the act of registering a schema has no effect on the status of any instance documents already loaded into Oracle XML DB Repository that reference the XML schema. Because the XML schema was not yet registered, such instance documents were non-schema-based when they were loaded. They remain non-schema-based after the schema is registered.

You must delete such instance documents, and reload them after registering the schema, in order to obtain schema-based documents.

Oracle XML Storage Tutorial.

È possibile posizionare lo schema nella stessa directory dell'XML che lo fa riferimento. In questo caso, è sufficiente specificare il nome del file in questo modo:

xsi:noNamespaceSchemaLocation="Example-01.xsd" 

(valido riferimento relativo URI)

+0

Beh, come lei ha detto che ho cambiato il documento XML come questo Ma ancora ottengo lo stesso errore. – dariyoosh

+0

@ stefan nebesnak Uso targetNameSpace e quindi xsi: noNamespaceSchemaLocation non è appropriato per questo problema. Inoltre, solo lo schema è incorporato (intendo registrato nel database) il documento XML è solo un oggetto XMLType locale il cui ambito è limitato a un DECLARE locale ... BEGIN ... END; Blocco PL/SQL, quindi non è necessario eliminare e ricaricare i documenti poiché non sono integrati. Eppure, ti ringrazio per l'osservazione (che non sapevo) e per i link – dariyoosh