Partilhar via


Estendendo o DOM

O Microsoft .NET Framework inclui um conjunto base de classes que fornece uma implementação do DOM (Document Object Model) XML. O XmlNode, e suas classes derivadas, fornece métodos e propriedades que permitem navegar, consultar e modificar o conteúdo e a estrutura de um documento XML.

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

Existem duas diretrizes gerais ao derivar novas classes:

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

  • Exceto para os métodos de criação de nó, é recomendável que, ao substituir uma função, você sempre chame a versão base da função e, em seguida, adicione qualquer processamento adicional.

Criando suas próprias instâncias de nó

A XmlDocument classe 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 para que suas instâncias de nó sejam criadas quando um documento for carregado. Por exemplo, se você tiver estendido a XmlElement classe, você herdaria a XmlDocument classe e substituiria o CreateElement método.

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

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, derive sua classe de uma das classes DOM existentes. Em seguida, você pode substituir qualquer um dos métodos virtuais ou propriedades na classe base ou adicionar o seu próprio.

No exemplo a seguir, uma nova classe é criada, que implementa a XmlElement classe e a IXmlLineInfo interface. Métodos e propriedades adicionais são definidos para permitir que os usuários reúnam informações de linha.

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 de nó

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

O processo de manipulação de eventos funciona exatamente da mesma forma nas classes derivadas que nas classes DOM originais.

Para obter mais informações sobre a manipulação de eventos de nó, consulte Eventos e XmlNodeChangedEventHandler.

Atributos padrão e o método CreateElement

Se você estiver substituindo o método em uma classe derivada, os CreateElement atributos padrão não serão adicionados quando você estiver criando novos elementos durante a edição do documento. Este é apenas um problema durante a edição. Como o CreateElement método é responsável por adicionar atributos padrão a um XmlDocument, você deve codificar CreateElement essa funcionalidade no método. Se você estiver carregando um XmlDocument que inclui atributos padrão, eles serão manipulados corretamente. Para obter mais informações sobre atributos padrão, consulte Criando novos atributos para elementos no DOM.

Consulte também