Christian Castelli
a- a+

Validazione documenti XML

COLDFUSION E XML

Validazione dei documenti XML

ColdFusion fornisce funzioni per controllare se un documentoXML è ben formato o valido secondo un XML Schemao un DTD fornito. ci sono funzioni addizionaliper controllare differenti parti di un documento XML. Questefunzioni vengono spiegate qui sotto.

IsXML()

La funzione IsXML() determina se la stringapassata come argomento è un documento XML ben formato.Ritorna true se lo è, altrimenti false.L'esempio seguente mostra come usare tale funzione.

Es 10: IsXML.cfm

<cfparam name="FORM.XmlText"     default="<Name> <FirstName>George</FirstName> <LastName>Washington</LastName> </Name>">  <html>  <head>  <title>IsXML()</title>  </head>  <body>  <h1>XML Test</h1>  <cfoutput>  <form method="post" action="#CGI.SCRIPT_NAME#">  <textarea name="XmlText" cols="60" rows="10">#FORM.XmlText#</textarea>  <br>  <input name="SubmitButton" type="submit" value="Check XML">  <cfif isDefined("FORM.SubmitButton")>   <cfif IsXML(FORM.XmlText)>    <span style="margin-left:200px;color:green">XML is well formed.</span>   <cfelse>    <span style="margin-left:200px;">XML is not well formed.</span>   </cfif>  </cfif>  </form>  </cfoutput>  </body>  </html>

 

<a href="/img/22/iframe_CF_xml10.html" title="Vedi esempio">Vedi codice</a>;

 

La pagina mostra semplicemente un form contenente unatextarea per contenenre il documento XML. quando il formviene sottomesso, la pagina usa la funzioneisXML() per controllare se il testo inseritorappresenta un documento ben formato e mostra un messaggiocon il risultato di tale validazione.

Quando la pagina viene aperta per la prima volta, apparecosì:

isxml1
Fig 6a: documento xml risultante dall'esempio10

Quando si sottomette il form con un documento ben formato, lapagina mostra un messaggio di successo in basso a destra:

isxml2
Fig 6b: risultato della validazione dell'esempio10

Quando si sottomette il form con un documento XML non benformato, la pagina mostra un messaggio di errore in rosso:

isxml3
Fig 6c: risultato della validazione dell'esempio10

XmlValidate()

La funzione XmlValidate() viene usata pervalidare un documento XML partendo da un XML Schema o un DTD.La funzione prende i seguenti parametri:

I parametri di XmlValidate()

Parametro

Descrizione

xmlDoc Obbligatorio. Può assumere uno qualsiasi deiseguenti valori:
  • una stringa XML
  • un percorso assoluto o un URL ad un file XML
  • un XML DOM
validator Opzionale. Può assumere uno qualsiasi deiseguenti valori:
  • una stringa contenente un DTD o un XML Schema
  • un percorso assoluto o un URL ad un DTD o un XML Schema

La funzione ritorna una struttura contenente i seguenticampi:

  • Status - un valore booleano indicante se la validazione ha avuto successo;
  • Errors - un array contenente gli errori;
  • FatalErrors - un array contenente errori fatali, di solito indicanti che il documento XML non è ben formato;
  • Warnings - un array contenete gli avvertimenti.

Per illustrare quanto esposto fin'ora, useremo ilseguente semplice XML Schema:

Es. 11a: Name.xsd

<?xml version="1.0" encoding="UTF-8"?>  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">   <xs:element name="Name">    <xs:complexType>     <xs:sequence><xs:element name="FirstName" type="xs:string"/><xs:element name="LastName" type="xs:string"/     </xs:sequence>     <xs:attribute name="Title" type="xs:string" use="optional"/>    </xs:complexType>   </xs:element>  </xs:schema>

 

<a href="/img/22/iframe_CF_xml11a.html" title="Vedi esempio">Vedi codice</a>;

 

Tale schema richiede che l'elemento Name deldocumento abbia due nodi figli, FirstName andLastName, e un attributo opzionale,Title.

ColdFusion usa il parser Xerces per validare i documenti XML. Pereffettuare correttamente la validazione quando viene usato ilparametro di validazione, il parser richiede l'utilizzodegli attributi xmlns:xsi exsi:noNamespaceSchemaLocation. Per illustrarequanto detto, viene presentata una dimostrazionedell'utilizzo di IsXML().

Es. 11b: XmlValidate.cfm

<cfparam name="FORM.XmlText"    default="<Name xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'  xsi:noNamespaceSchemaLocation=''> <FirstName>George</FirstName> <LastName>Washington</LastName> </Name>">  <html>  <head>  <title>XmlValidate()</title>  </head>  <body>  <h1>XML Validation Test</h1>  <cfoutput>  <form method="post" action="#CGI.SCRIPT_NAME#">  <textarea name="XmlText" cols="60" rows="10">#FORM.XmlText#</textarea>  <br><input name="SubmitButton" type="submit" value="Validate XML">  <cfif isDefined("FORM.SubmitButton")>   <cfset structResults = XmlValidate(FORM.XmlText,ExpandPath("Name.xsd"))>   <cfif structResults.status>    <span style="margin-left:200px;color:green">XML is valid.</span>   <cfelse>    <span style="margin-left:200px;">XML is not valid.</span>    <div style="margin-top:10px">    <cfif ArrayLen(structResults.Errors)>     <b>Errors:</b>     <ol style="margin-top:0px"><cfloop index="i" from="1" to="#ArrayLen(structResults.Errors)#"> <li>#structResults.errors[i]#</li></cfloop>     </ol>    </cfif>    <cfif ArrayLen(structResults.FatalErrors)>     <b>Fatal Errors:</b>     <ol style="margin-top:0px"><cfloop index="i" from="1" to="#ArrayLen(structResults.FatalErrors)#"> <li>#structResults.fatalErrors[i]#</li></cfloop>     </ol>    </cfif>    <cfif ArrayLen(structResults.Warnings)>     <b>Warnings:</b>     <ol style="margin-top:0px"><cfloop index="i" from="1" to="#ArrayLen(structResults.Warnings)#"> <li>#structResults.warnings[i]#</li></cfloop>     </ol>    </cfif>    </div>   </cfif>  </cfif>  </form>  </cfoutput>  </body>  </html>

 

<a href="/img/22/iframe_CF_xml11b.html" title="Vedi esempio">Vedi codice</a>;

 

quando la pagina viene aperta per la prima volta, apparecosì:

xmlvaltest1
Fig 7a: output iniziale dell'esempio 11

Quando il form viene sottomesso con un documento XML validomla pagina mostra un messaggi odi successo in basso adestra...

xmlvalidtest2
Fig 7b: risultato della validazione per l'esempio11

altrimenti vengono mostrati gli errori presenti neldocumento:

xmlvalidtest3
Fig 7c: risultato della validazione per l'esempio11

Il documento XML ha svariati problemi:

  • Gli errori sono problemi con la validità del documento XML in accordo allo schema specificato. In questo caso, l'attributo title dovrebbe avere la "T" maiuscola e non è permesso utilizzare l'elemento MiddleName;
  • Gli errori fatali sono problemi legati alla well-formedness di un documento XML. In questo caso, l'elemento di chiusura di LastName dovrebbe avere la "N" maiuscola;
  • non ci sono avvertimenti, che generalmente sono difficili da produrre nella validazione del parser.

IsXmlDoc(), IsXmlRoot(), IsXmlElem(), IsXmlAttribute(),IsXmlNode()

  • IsXmlDoc(): ritorna true se il parametro fornito è un oggetto rappresentante un documento XML;
  • IsXmlRoot(): ritorna true se il parametro fornito è l'elemento radice di un documento XML;
  • IsXmlElem(): ritorna true se il parametro fornito è un elemento XML;
  • IsXmlAttribute(): ritorna true se il parametro fornito è un attributo XML;
  • IsXmlNode():ritorna true se il parametro fornito è un nodo XML.

I file seguenti mostrano come usare le funzioni introdottepoco fa.

Es. 12: XmlParts.cfm

<cfset xmlGeorge=XMLParse(ExpandPath("George.xml"))>  <html>  <head>  <title>XML Parts</title>  <style type="text/css">  .YES {background-color:#00cc00; font-weight:bold;}  .NO {color:#ff0000;}  </style>  </head>  <body>  <h1>XML Parts</h1>  <table border="1" cellpadding="2" cellspacing="0">  <tr>   <th>#</th>   <th>XML Part</th>   <th>IsXmlDoc()</th>   <th>IsXmlRoot()</th>   <th>IsXmlElem()</th>   <th>IsXmlAttribute()</th>   <th>IsXmlNode()</th>  </tr>  <cfoutput>  <cfset part = xmlGeorge>  <tr>   <td>1</td>   <td>xmlGeorge</td>   <td class="#IsXmlDoc(part)#">#IsXmlDoc(part)#</td>   <td class="#IsXmlRoot(part)#">#IsXmlRoot(part)#</td>   <td class="#IsXmlElem(part)#">#IsXmlElem(part)#</td>   <td class="#IsXmlAttribute(part)#">#IsXmlAttribute(part)#</td>   <td class="#IsXmlNode(part)#">#IsXmlNode(part)#</td>  </tr>  <cfset part = xmlGeorge.Name>  <tr>   <td>2</td>   <td>xmlGeorge.Name</td>   <td class="#IsXmlDoc(part)#">#IsXmlDoc(part)#</td>   <td class="#IsXmlRoot(part)#">#IsXmlRoot(part)#</td>   <td class="#IsXmlElem(part)#">#IsXmlElem(part)#</td>   <td class="#IsXmlAttribute(part)#">#IsXmlAttribute(part)#</td>   <td class="#IsXmlNode(part)#">#IsXmlNode(part)#</td>  </tr>  <cfset part = xmlGeorge.Name.XmlAttributes.Title>  <tr>   <td>3</td>   <td>xmlGeorge.Name.XmlAttributes.Title</td>   <td class="#IsXmlDoc(part)#">#IsXmlDoc(part)#</td>   <td class="#IsXmlRoot(part)#">#IsXmlRoot(part)#</td>   <td class="#IsXmlElem(part)#">#IsXmlElem(part)#</td>   <td class="#IsXmlAttribute(part)#">#IsXmlAttribute(part)#</td>   <td class="#IsXmlNode(part)#">#IsXmlNode(part)#</td>  </tr>  <cfset part = xmlGeorge.Name.FirstName>  <tr>   <td>4</td>   <td>xmlGeorge.Name.FirstName</td>   <td class="#IsXmlDoc(part)#">#IsXmlDoc(part)#</td>   <td class="#IsXmlRoot(part)#">#IsXmlRoot(part)#</td>   <td class="#IsXmlElem(part)#">#IsXmlElem(part)#</td>   <td class="#IsXmlAttribute(part)#">#IsXmlAttribute(part)#</td>   <td class="#IsXmlNode(part)#">#IsXmlNode(part)#</td>  </tr>  <cfset part = xmlGeorge.Name.XmlChildren[1]>  <tr>   <td>5</td>   <td>xmlGeorge.Name.XmlChildren[1]</td>   <td class="#IsXmlDoc(part)#">#IsXmlDoc(part)#</td>   <td class="#IsXmlRoot(part)#">#IsXmlRoot(part)#</td>   <td class="#IsXmlElem(part)#">#IsXmlElem(part)#</td>   <td class="#IsXmlAttribute(part)#">#IsXmlAttribute(part)#</td>   <td class="#IsXmlNode(part)#">#IsXmlNode(part)#</td>  </tr>  <cfset part = xmlGeorge.Name.FirstName.XmlText>  <tr>   <td>6</td>   <td>xmlGeorge.Name.FirstName.XmlText</td>   <td class="#IsXmlDoc(part)#">#IsXmlDoc(part)#</td>   <td class="#IsXmlRoot(part)#">#IsXmlRoot(part)#</td>   <td class="#IsXmlElem(part)#">#IsXmlElem(part)#</td>   <td class="#IsXmlAttribute(part)#">#IsXmlAttribute(part)#</td>   <td class="#IsXmlNode(part)#">#IsXmlNode(part)#</td>  </tr>  </table>  </cfoutput>  </body>  </html>

 

<a href="/img/22/iframe_CF_xml12.html" title="Vedi esempio">Vedi codice</a>;

 

La pagina mostrerà il seguente risultato:

xmlparts
Fig 8: risultato dell'esempio 12

Quanto visto è piuttosto intuitivo. Le uniche sorpresesono le modalità con cui vengono gestiti nodi edattributi. Secondo quando mostrato dalla terza riga,l'attributo Title non è né un attributoné un nodo XML. E secondo quanto mostrato nella sestariga, il testo all'interno dell'elementoFirstElement non rappresenta un nodo XML.L'attributo Title è certamente unattributo XML e tutti gli attributi e i testi in un documentoXML sono nodi XML; ad ogni modo ColdFusion tratta gliattributi come proprietà di un elemento, non comenodi, e tratta il testo come puro testo piuttosto che cometesto appartenente ad un nodo XML.

XmlNodes Array

Ogni elemento possiede un array XmlNodes, checontiene i nodi degli elementi degli elementi, i noditestuali, i nodi dei commenti, e le sezioni CDATA. Noncontiene nodi degli attributi degli elementi. Per accedereagli attributi, si deve usare la strutturaXmlAttributes.

XmlGetNodeType()

La funzione XmlGetNodeType() viene usata per determinare iltipo del nodo passato come parametro. I due esempi seguentimostrano come agisce la funzione.

Es. 13: GetNodeType.cfm

<cfset xmlGeorge=XMLParse(ExpandPath("George.xml"))>  <html>  <head>  <title>XmlGetNodeType()</title>  </head>  <body>  <h1>XmlGetNodeType()</h1>  <cfoutput>  <ol>   <cfset part = xmlGeorge>   <li>    xmlGeorge:     <cftry>     #XmlGetNodeType(part)#     <cfcatch type="any"><span style="">#cfcatch.Message#</span></cfcatch>    </cftry>   </li><cfset part = xmlGeorge.Name>   <li>    xmlGeorge.Name:     <cftry>     #XmlGetNodeType(part)#     <cfcatch type="any"><span style="">#cfcatch.Message#</span></cfcatch>    </cftry>   </li><cfset part = xmlGeorge.Name.XmlAttributes.Title>   <li>    xmlGeorge.Name.XmlAttributes.Title:     <cftry>     #XmlGetNodeType(part)#     <cfcatch type="any"><span style="">#cfcatch.Message#</span></cfcatch>    </cftry>   </li><cfset part = xmlGeorge.Name.FirstName>   <li>    xmlGeorge.Name.FirstName:     <cftry>     #XmlGetNodeType(part)#     <cfcatch type="any"><span style="">#cfcatch.Message#</span></cfcatch>    </cftry>   </li><cfset part = xmlGeorge.Name.XmlChildren[1]>   <li>    xmlGeorge.Name.XmlChildren[1]:     <cftry>     #XmlGetNodeType(part)#     <cfcatch type="any"><span style="">#cfcatch.Message#</span></cfcatch>    </cftry>   </li><cfset part = xmlGeorge.Name.FirstName.XmlText>   <li>    xmlGeorge.Name.FirstName.XmlText:     <cftry>     #XmlGetNodeType(part)#     <cfcatch type="any"><span style="">#cfcatch.Message#</span></cfcatch>    </cftry>   </li>  </ol>  </cfoutput>  </body>  </html>

 

<a href="/img/22/iframe_CF_xml13.html" title="Vedi esempio">Vedi codice</a>;

 

Il risultato degli esempi precedenti viene mostrato nellafigura sottostante:

xmlgetnodetype
Fig 9: risultato dell'esempio 13

Es. 14: XmlNodes.cfm

<cfset xmlGeorge=XMLParse(ExpandPath("George2.xml"))>  <cfset nameNodes = xmlGeorge.Name.XmlNodes>  <html>  <head>  <title>XmlNodes()</title>  </head>  <body>  <h1>XmlNodes()</h1>  <ol>  <cfoutput>  <cfloop index="i" from="1" to="#ArrayLen(nameNodes)#">   <li>#XmlGetNodeType(nameNodes[i])# - #IsXmlNode(nameNodes[i])#</li>  </cfloop>  </cfoutput>  </ol>  </body>  </html>

 

<a href="/img/22/iframe_CF_xml14.html" title="Vedi esempio">Vedi codice</a>;

 

Il risultato dell'esempio precedente viene mostrato nellafigura sottostante:

xmlnodes
Fig 10: risultato dell'esempio 14

Noterete che ha importanza come l'elemento vienerichiamato. Quando i nodi testuali vengono richiamatiattraverso la notazione a punti (ad esempioxmlGeorge.Name.FirstName.XmlText), non vengonotrattati come nodi XML, al contrario di quando vengonorichiamati attraverso l'array XmlNodes. La stessa cosavale per i nodi dei commenti e delle sezioni CDATA. Per andarsul sicuro, dovreste sempre testare un possibile nodo con lafunzione IsXmlNode() prima di trattarlo come unnodo XML.


Conclusioni

Con quest'ultima parte, riguardante XML in ColdFusion,termina la guida introduttiva a ColdFusion.



Ti potrebbe interessare anche

commenta la notizia