Mapping della gerarchia di oggetti in dati XML
Quando un documento XML è in memoria, la rappresentazione concettuale è una struttura. Per la programmazione, si accede ai nodi della struttura attraverso la sua gerarchia. Nell'esempio che segue viene mostrato come il contenuto XML viene trasformato in nodi.
Mentre l'XML viene letto nel DOM, i pezzi sono tradotti in nodi e questi ultimi mantengono metadati aggiuntivi a essi relativi, come il tipo di nodo e i valori. Il tipo di nodo è il suo oggetto ed è ciò che determina quali azioni possono essere eseguite e quali proprietà possono essere impostate o recuperate.
Si supponga ad esempio di disporre del semplice XML che segue:
Input
<book>
<title>The Handmaid's Tale</title>
</book>
L'input è rappresentato in memoria come la seguente struttura di nodi con la proprietà del tipo di nodo associata:
Rappresentazione della struttura dei nodi del libro e del titolo
L'elemento book
diventa un oggetto XmlElement, l'elemento successivo, title
, diventa anch'esso un XmlElement, mentre il contenuto dell'elemento diventa un oggetto XmlText. Osservando i metodi e le proprietà XmlElement, si può notare che questi sono diversi dai metodi e dalle proprietà disponibili in un oggetto XmlText. È quindi fondamentale sapere quale tipo di nodo diventerà il tag XML, perché in base a questo vengono determinate le azioni che possono essere eseguite.
Nell'esempio seguente vengono letti i dati XML e viene scritto un testo diverso a seconda del tipo di nodo, utilizzando il seguente file di dati XML, items.xml, come input:
Input
<?xml version="1.0"?>
<!-- This is a sample XML document -->
<!DOCTYPE Items [<!ENTITY number "123">]>
<Items>
<Item>Test with an entity: &number;</Item>
<Item>test with a child element <more/> stuff</Item>
<Item>test with a CDATA section <![CDATA[<456>]]> def</Item>
<Item>Test with a char entity: A</Item>
<!-- Fourteen chars in this element.-->
<Item>1234567890ABCD</Item>
</Items>
Nel seguente esempio di codice viene letto il file items.xml e vengono visualizzate le informazioni per ogni tipo di nodo.
Imports System
Imports System.IO
Imports System.Xml
Public Class Sample
Private Const filename As String = "items.xml"
Public Shared Sub Main()
Dim txtreader As XmlTextReader = Nothing
Dim reader As XmlValidatingReader = Nothing
Try
' Load the reader with the data file and
'ignore all whitespace nodes.
txtreader = New XmlTextReader(filename)
txtreader.WhitespaceHandling = WhitespaceHandling.None
' Implement the validating reader over the text reader.
reader = New XmlValidatingReader(txtreader)
reader.ValidationType = ValidationType.None
' Parse the file and display each of the nodes.
While reader.Read()
Select Case reader.NodeType
Case XmlNodeType.Element
Console.Write("<{0}>", reader.Name)
Case XmlNodeType.Text
Console.Write(reader.Value)
Case XmlNodeType.CDATA
Console.Write("<![CDATA[{0}]]>", reader.Value)
Case XmlNodeType.ProcessingInstruction
Console.Write("<?{0} {1}?>", reader.Name, reader.Value)
Case XmlNodeType.Comment
Console.Write("<!--{0}-->", reader.Value)
Case XmlNodeType.XmlDeclaration
Console.Write("<?xml version='1.0'?>")
Case XmlNodeType.Document
Case XmlNodeType.DocumentType
Console.Write("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value)
Case XmlNodeType.EntityReference
Console.Write(reader.Name)
Case XmlNodeType.EndElement
Console.Write("</{0}>", reader.Name)
End Select
End While
Finally
If Not (reader Is Nothing) Then
reader.Close()
End If
End Try
End Sub 'Main ' End class
End Class 'Sample
[C#]
using System;
using System.IO;
using System.Xml;
public class Sample
{
private const String filename = "items.xml";
public static void Main()
{
XmlTextReader txtreader = null;
XmlValidatingReader reader = null;
try
{
// Load the reader with the data file and ignore
// all whitespace nodes.
txtreader = new XmlTextReader(filename);
txtreader.WhitespaceHandling = WhitespaceHandling.None;
// Implement the validating reader over the text reader.
reader = new XmlValidatingReader(txtreader);
reader.ValidationType = ValidationType.None;
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
Console.Write("<{0}>", reader.Name);
break;
case XmlNodeType.Text:
Console.Write(reader.Value);
break;
case XmlNodeType.CDATA:
Console.Write("<![CDATA[{0}]]>", reader.Value);
break;
case XmlNodeType.ProcessingInstruction:
Console.Write("<?{0} {1}?>", reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
Console.Write("<!--{0}-->", reader.Value);
break;
case XmlNodeType.XmlDeclaration:
Console.Write("<?xml version='1.0'?>");
break;
case XmlNodeType.Document:
break;
case XmlNodeType.DocumentType:
Console.Write("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
break;
case XmlNodeType.EntityReference:
Console.Write(reader.Name);
break;
case XmlNodeType.EndElement:
Console.Write("</{0}>", reader.Name);
break;
}
}
}
finally
{
if (reader!=null)
reader.Close();
}
}
} // End class
Dall'output dell'esempio è possibile osservare il mapping dei dati nei tipi di nodo.
Output
<?xml version='1.0'?><!--This is a sample XML document --><!DOCTYPE Items [<!ENTITY number "123">]<Items><Item>Test with an entity: 123</Item><Item>test with a child element <more> stuff</Item><Item>test with a CDATA section <![CDATA[<456>]]> def</Item><Item>Test with a char entity: A</Item><--Fourteen chars in this element.--><Item>1234567890ABCD</Item></Items>
Esaminando l'input riga per riga e utilizzando l'output generato dal codice, è possibile utilizzare la tabella seguente per analizzare quale nodo ha generato determinate righe di output e capire quindi quali dati XML sono diventati un determinato tipo di nodo.
Input | Output | Test del tipo di nodo |
---|---|---|
<?xml version="1.0"?> | <?xml version='1.0'?> | XmlNodeType.XmlDeclaration |
<!-- This is a sample XML document --> | <!--This is a sample XML document --> | XmlNodeType.Comment |
<!DOCTYPE Items [<!ENTITY number "123">]> | <!DOCTYPE Items [<!ENTITY number "123">] | XmlNodeType.DocumentType |
<Items> | <Items> | XmlNodeType.Element |
<Item> | <Item> | XmlNodeType.Element |
Test with an entity: &number;</Item> | Test with an entity: 123 | XmlNodeType.Text |
</Item> | </Item> | XmlNodeType.EndElement |
<Item> | <Item> | XmNodeType.Element |
test with a child element | test with a child element | XmlNodeType.Text |
<more> | <more> | XmlNodeType.Element |
stuff | stuff | XmlNodeType.Text |
</Item> | </Item> | XmlNodeType.EndElement |
<Item> | <Item> | XmlNodeType.Element |
test with a CDATA section | test with a CDATA section | XmlTest.Text |
<![CDATA[<456>]]> | <![CDATA[<456>]]> | XmlTest.CDATA |
def | def | XmlNodeType.Text |
</Item> | </Item> | XmlNodeType.EndElement |
<Item> | <Item> | XmlNodeType.Element |
Test with a char entity: A | Test with a char entity: A | XmlNodeType.Text |
</Item> | </Item> | XmlNodeType.EndElement |
<!-- Fourteen chars in this element.--> | <!-- Fourteen chars in this element.--> | XmlNodeType.Comment |
<Item> | <Item> | XmlNodeType.Element |
1234567890ABCD | 1234567890ABCD | XmlNodeType.Text |
</Item> | </Item> | XmlNodeType.EndElement |
</Items> | </Items> | XmlNodeType.EndElement |
È necessario sapere quale tipo di nodo viene assegnato, in quanto in base al tipo di nodo vengono determinate le azioni valide e il tipo di proprietà che è possibile impostare e recuperare.
La creazione di nodi per caratteri spazio viene controllata dal flag PreserveWhitespace. Per ulteriori informazioni, vedere Gestione dei caratteri spazio e dei caratteri spazio significativi durante il caricamento del DOM
Per aggiungere nuovi nodi al DOM, vedere Inserimento di nodi in un documento XML. Per rimuovere nodi dal DOM, vedere Rimozione di nodi, contenuto e valori da un documento XML. Per modificare il contenuto dei nodi nel DOM, vedere Modifica di nodi, contenuto e valori in un documento XML.
Vedere anche
Modello a oggetti di documenti XML (Document Object Model, DOM)