Domanda

Voglio prova (vero o falso) se un file XML arbitrario corrisponde un determinato schema.

Per quello che vale, lo schema è lo schema di Word 2003 WordML, che Microsoft definisce utilizzando una lista di circa 7 file *.xsd.

Uno di questi file include anche il file xml.xsd W3C, includendo la seguente dichiarazione:

<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"
    schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import>

Sto usando il codice .NET come il seguente a fare la convalida:

   public static void validate(string filename)
    {
       XmlReaderSettings settings = new XmlReaderSettings();
       settings.Schemas.Add(
           "http://schemas.microsoft.com/office/word/2003/wordml",
           //to get this file I downloaded "Office 2003: XML Reference Schemas", i.e. "Office2003XMLSchema.exe" 
           @"C:\Program Files\Microsoft Office 2003 Developer Resources\Microsoft Office 2003 XML Reference Schemas\WordprocessingML Schemas\wordnet.xsd"
           );
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler);
        XmlReader xmlReader = XmlReader.Create(filename, settings);
        while (xmlReader.Read()) { }
   }

Il mio problema è che se corro questo codice su una macchina che non è collegato a Internet, allora ottengo un errore XmlSchemaValidationException nel senso che non riesce a trovare xml.xsd.

Per risolvere questo problema, ho scaricato una copia di xml.xsd, e inserirlo in modo esplicito con il metodo settings.Schemas.Add:. La validazione ora funziona correttamente quando la macchina non è connesso a Internet

Tuttavia, quando la macchina è collegata a internet, ora ottiene un errore che dice che The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared..

Quindi, a quanto pare mi sia bisogno di aggiungere esplicitamente, o non fare, a seconda che la macchina è in grado di scaricare in silenzio da internet (o forse anche precedentemente stato in grado di scaricare, e lo ha memorizzato nella cache da qualche parte ).

Quindi, è "dannato se lo faccio e dannato se non lo faccio". Ho bisogno di provare un modo, intercettare l'eccezione e quindi provare il contrario? O c'è una soluzione più elegante?

È stato utile?

Soluzione

Non possiamo vedere il tuo codice, ma In molte implementazioni questo viene gestito reindirizzando la richiesta di .xsd alla copia locale tramite un resolver catalogo. C'è una proprietà XmlReaderSettings.XmlResolver che può essere usato per questo. Vedere XMLCatalog.net per un'implementazione di Apache con licenza è possibile utilizzare.

Un effetto collaterale di questo è che si può tenere tutti gli schemi memorizzati nella cache locale. Questo è particolarmente importante in quanto W3C bloccherà eccessiva legge al loro sito e in modo casuale il codice (o peggio, il codice del vostro cliente) inizierà a fallire.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top