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
, NodeRemoved
e 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.