Compartilhar via


Estendendo os DOM

O Microsoft .NET Framework inclui um conjunto básico de classes que fornece uma implementação de DOM (XML Document Object Model). XmlNode, e suas classes derivadas, fornecem métodos e propriedades que permitem que você navega, consulte, e o conteúdo e a estrutura de um documento XML.

Quando o conteúdo XML é carregado na memória usando os DOM, os nós criados contêm informações como o nome de nó, tipo de nó, e assim por diante. Pode haver ocasiões as onde você requer informações específicas do nó que classes base não fornecem. Por exemplo, você pode desejar consultar o número da linha e posição do nó. Nesse caso, você pode derivar novas classes de classes DOM existentes e adicionar funcionalidade adicional.

Há duas diretrizes gerais para derivar novas classes:

  • É recomendável que você nunca deriva de classe de XmlNode . Em vez disso, é recomendável que você derivado classes de classe correspondente ao tipo de nó que você está interessado. Por exemplo, se você quiser retornar informações adicionais em nós de atributo, você pode derivar da classe de XmlAttribute .

  • A exceção dos métodos de criação de nó, é recomendável que substituir uma função, você sempre deve chamar a versão de base de função e adicionar qualquer processamento adicional.

Criando suas próprias instâncias do nó

A classe de XmlDocument contém métodos de criação de nó. Quando um arquivo XML é carregado, esses métodos são chamados para criar os nós. Você pode substituir esses métodos de modo que as instâncias do nó são criados quando um documento é carregado. Por exemplo, se você estendeu a classe de XmlElement , você herdaria a classe de XmlDocument e poderia substituir o método de CreateElement .

O exemplo a seguir mostra como substituir o método de CreateElement retornar sua implementação da classe de XmlElement .

Class LineInfoDocument
    Inherits XmlDocument
        Public Overrides Function CreateElement(prefix As String, localname As String, nsURI As String) As XmlElement
        Dim elem As New LineInfoElement(prefix, localname, nsURI, Me)
        Return elem
    End Function 'CreateElement
End Class 'LineInfoDocument
class LineInfoDocument : XmlDocument
{
    public override XmlElement CreateElement(string prefix, string localname, string nsURI)
    {
        LineInfoElement elem = new LineInfoElement(prefix, localname, nsURI, this);
        return elem;
    }
}

Estendendo uma classe

Para estender uma classe derivada, a classe de uma das classes DOM existentes. Você pode então substitua alguns dos métodos ou propriedades virtuais na classe base, ou adicione seus próprios.

No exemplo a seguir, uma nova classe é criada, que implementa a classe de XmlElement e a interface de IXmlLineInfo . Os métodos e propriedades adicionais são definidos que permite que os usuários coleta a linha informações.

Class LineInfoElement
   Inherits XmlElement
   Implements IXmlLineInfo
   Private lineNumber As Integer = 0
   Private linePosition As Integer = 0

   Friend Sub New(prefix As String, localname As String, nsURI As String, doc As XmlDocument)
      MyBase.New(prefix, localname, nsURI, doc)
      CType(doc, LineInfoDocument).IncrementElementCount()
   End Sub

   Public Sub SetLineInfo(linenum As Integer, linepos As Integer)
      lineNumber = linenum
      linePosition = linepos
   End Sub

   Public ReadOnly Property LineNumber() As Integer
      Get
         Return lineNumber
      End Get
   End Property

   Public ReadOnly Property LinePosition() As Integer
      Get
         Return linePosition
      End Get
   End Property

   Public Function HasLineInfo() As Boolean
      Return True
   End Function
End Class ' End LineInfoElement class.
class LineInfoElement : XmlElement, IXmlLineInfo {
   int lineNumber = 0;
   int linePosition = 0;
   internal LineInfoElement( string prefix, string localname, string nsURI, XmlDocument doc ) : base( prefix, localname, nsURI, doc ) {
       ( (LineInfoDocument)doc ).IncrementElementCount();
  }
  public void SetLineInfo( int linenum, int linepos ) {
      lineNumber = linenum;
      linePosition = linepos;
  }
  public int LineNumber {
     get {
       return lineNumber;
     }
  }
  public int LinePosition {
      get {
        return linePosition;
      }
  }
  public bool HasLineInfo() {
    return true;
  }
} // End LineInfoElement class.

Exemplo

O exemplo a seguir conta o número de elementos em um documento XML:

Imports System.Xml
Imports System.IO

Class LineInfoDocument
   Inherits XmlDocument

   Private elementCount As Integer

   Friend Sub New()
      elementCount = 0
   End Sub

   Public Overrides Function CreateElement(prefix As String, localname As String, nsURI As String) As XmlElement
      Dim elem As New LineInfoElement(prefix, localname, nsURI, Me)
      Return elem
   End Function

   Public Sub IncrementElementCount()
      elementCount += 1
   End Sub

   Public Function GetCount() As Integer
      Return elementCount
   End Function
End Class 'End LineInfoDocument class.

Class LineInfoElement
   Inherits XmlElement

   Friend Sub New(prefix As String, localname As String, nsURI As String, doc As XmlDocument)
      MyBase.New(prefix, localname, nsURI, doc)
      CType(doc, LineInfoDocument).IncrementElementCount()
   End Sub 'New
End Class 'LineInfoElement
 _ 'End LineInfoElement class.

Public Class Test

   Private filename As [String] = "book.xml"

   Public Shared Sub Main()

      Dim doc As New LineInfoDocument()
      doc.Load(filename)
      Console.WriteLine("Number of elements in {0}: {1}", filename, doc.GetCount())
   End Sub
End Class
using System;
using System.Xml;
using System.IO;

class LineInfoDocument : XmlDocument {

  int elementCount;
  internal LineInfoDocument():base() {
    elementCount = 0;
  }

  public override XmlElement CreateElement( string prefix, string localname, string nsURI) {
    LineInfoElement elem = new LineInfoElement(prefix, localname, nsURI, this );
    return elem;
  }

  public void IncrementElementCount() {
     elementCount++;
  }

  public int GetCount() {
     return elementCount;
  }
} // End LineInfoDocument class.

class LineInfoElement:XmlElement {

    internal LineInfoElement( string prefix, string localname, string nsURI, XmlDocument doc ):base( prefix,localname,nsURI, doc ){
      ((LineInfoDocument)doc).IncrementElementCount();
    }
} // End LineInfoElement class.

public class Test {

  const String filename = "book.xml";
  public static void Main() {

     LineInfoDocument doc =new LineInfoDocument();
     doc.Load(filename);
     Console.WriteLine("Number of elements in {0}: {1}", filename, doc.GetCount());

  }
}

Entrada

book.xml

<!--sample XML fragment-->
<book genre='novel' ISBN='1-861001-57-5' misc='sale-item'>
  <title>The Handmaid's Tale</title>
  <price>14.95</price>
</book>

Saída

Number of elements in book.xml: 3

Manipulador de eventos do nó

A implementação do .NET Framework DOM também inclui um sistema de eventos que permite que você receber e manipular eventos quando os nós em um documento XML são alterados. Usando as classes de XmlNodeChangedEventHandler e de XmlNodeChangedEventArgs , você pode capturar NodeChanged, NodeChanging, NodeInserted, NodeInserting, NodeRemoved, e eventos de NodeRemoving .

Os trabalhos de processo de manipulação de eventos exatamente em classes derivadas como em DOM original de classe.

Para saber mais sobre a manipulação de eventos do nó, confira Eventos e XmlNodeChangedEventHandler.

Atributos padrões e o método de CreateElement

Se você está substituindo o método de CreateElement em uma classe derivada, os atributos padrão não são adicionados quando você está criando novos elementos ao editar o documento. Este é apenas um problema ao editar. Porque o método de CreateElement é responsável para adicionar atributos padrão para XmlDocument, você deve codificar essa funcionalidade no método de CreateElement . Se você está carregando XmlDocument que inclui atributos padrão, serão tratados corretamente. Para saber mais sobre os atributos padrão, confira Criando novos atributos para os elementos em DOM.

Confira também