2009-08-20 15 views
42

Sto usando l'opzione --schema xmllint per convalidare la mia XML che assomiglia a questoxsd: il tipo di elemento booleano accetta "true" ma non "True". Come posso farcelo accettare?

<XML> 
<Active>True</Active> 
</XML> 

Nel mio file di schema, ho seguente riga che descrive elemento attivo.

<xsd:element name="Active" type="xsd:boolean" /> 

Quando eseguo xmllint, vengono visualizzati messaggi di errore che dice

/tmp/schema_validation.xml:73: elemento attivo: errore di validità schemi: Elemento 'attivo': 'True' non è un valore valido del tipo atomico 'xs: boolean'.

Quando cambio l'XML per

<Active>true</Active> 

Poi il messaggio di errore scompare.

Quindi, sembra xsd: boolean significa che è tutto in minuscolo "true/false" ma non "True/False" in xmllint .. La mia domanda è, come posso fare xmllint per accettare "True" per xsd: boolean genere? O ci sono diversi strumenti che posso usare per convalidare questo XML? Cambiare l'XML o lo schema non è la mia opzione a questo punto.

Grazie!

+0

Se la modifica del codice XML di origine o lo schema non è un'opzione, poi ho suggerirebbe di eseguire l'XML sorgente tramite una trasformazione che normalizza i valori booleani ai valori validi XSD corretti. –

+0

Ho pensato di farlo, ma avevo paura di modificare i valori che sono semplicemente "Vero". Per eample, se un elemento chiamato "Description" contiene valore "True", allora non voglio che sia convertito in "true".Non penso che ci sia un modo per sapere quale elemento applicare la normalizzazione o meno. –

+13

devi andare a monte: ferma la generazione di XML non valido all'origine. – Cheeso

risposta

88

Non è possibile.

In base allo XML Schema specification, un booleano è true o false. True non è valido:

 

    3.2.2.1 Lexical representation 
    An instance of a datatype that is defined as ·boolean· can have the 
    following legal literals {true, false, 1, 0}. 

    3.2.2.2 Canonical representation 
    The canonical representation for boolean is the set of 
    literals {true, false}. 

Se lo strumento che si sta utilizzando veramente convalida contro lo standard XML Schema, allora non si può convincerlo ad accettare True per un valore booleano.

+5

Grazie. È bene sapere che non c'è assolutamente alcun modo per ridefinire xsd: boolean –

+2

Per dirla in altro modo - se il software upstream genera True per qualcosa definito come XML Schema booleano, in realtà non sta generando XML, ma qualcos'altro che capita sembra simile. Il loro reparto marketing non dovrebbe quindi pretendere di utilizzare XML, poiché ora hanno invalidato il punto di utilizzo dell'XML: la possibilità di riutilizzare i parser comuni per motivi di efficienza. –

+3

Sarei diverso con @Oskar qui. Esistono strumenti che pretendono di generare XML ma di fatto non lo fanno, perché ciò che generano non è ben formato. Ma qui sembra che tu abbia un software upstream che genera XML che * è * ben formato, ma non è valido secondo il suo schema XML. È ancora XML. Non possono semplicemente affermare di essere conformi allo schema XML che stai utilizzando. – LarsH

46

xs:boolean è predefinito per quanto riguarda il tipo di input che accetta. Se avete bisogno di qualcosa di diverso, è necessario definire il proprio enumerazione:

<xs:simpleType name="my:boolean"> 
    <xs:restriction base="xs:string"> 
     <xs:enumeration value="True"/> 
     <xs:enumeration value="False"/> 
    </xs:restriction> 
    </xs:simpleType> 
+0

Grazie! Chiederò a qualcosa del genere di far parte dello schema in modo che io possa aggirare questo per ora. –

2

Se siete su Linux, o hanno cygwin disponibile su Windows, è possibile eseguire il codice XML di input attraverso un semplice script sed che sostituirà <Active>True</Active> con <Active>true</Active>, in questo modo:

cat <your XML file> | sed 'sX<Active>True</Active>X<Active>true</Active>X' | xmllint --schema - 

Se non sei, è comunque possibile utilizzare un pocessor non-validante XSLT (Xalan, Saxon ecc) per eseguire una semplice trasformazione XSLT sull'ingresso, e solo allora il tubo a xmllint.

Che xsl dovrebbe contenere qualcosa come di seguito, per l'esempio che hai elencato sopra (il processore XSLT dovrebbe essere 2,0 grado):

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/"> 
    <xsl:for-each select="XML"> 
     <xsl:for-each select="Active"> 
      <xsl:value-of select=" replace(current(), 'True','true')"/> 
     </xsl:for-each> 
    </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Attenzione: dubito che ci sia un "semplice script' sed' "abbastanza robusto da eseguire correttamente una sostituzione come questa su un file XML --- il tuo non lo è. – JonBrave

Problemi correlati