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: &#65;</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: &#65; 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)