De DOM uitbreiden
Microsoft .NET Framework bevat een basisset klassen die een implementatie van het XML Document Object Model (DOM) biedt. De XmlNode, en de afgeleide klassen, bieden methoden en eigenschappen waarmee u de inhoud en structuur van een XML-document kunt navigeren, doorzoeken en wijzigen.
Wanneer XML-inhoud in het geheugen wordt geladen met behulp van de DOM, bevatten de gemaakte knooppunten informatie zoals knooppuntnaam, knooppunttype, enzovoort. Er kunnen situaties zijn waarin u specifieke knooppuntgegevens nodig hebt die niet door de basisklassen worden verstrekt. U wilt bijvoorbeeld het regelnummer en de positie van het knooppunt zien. In dit geval kunt u nieuwe klassen afleiden uit de bestaande DOM-klassen en extra functionaliteit toevoegen.
Er zijn twee algemene richtlijnen bij het afleiden van nieuwe klassen:
Het wordt aanbevolen dat u nooit afgeleid bent van de XmlNode klasse. In plaats daarvan wordt u aangeraden klassen af te leiden van de klasse die overeenkomt met het knooppunttype waarin u geïnteresseerd bent. Als u bijvoorbeeld aanvullende informatie wilt retourneren over kenmerkknooppunten, kunt u deze afleiden uit de XmlAttribute klasse.
Met uitzondering van de methoden voor het maken van knooppunten wordt aanbevolen dat u bij het overschrijven van een functie altijd de basisversie van de functie aanroept en vervolgens aanvullende verwerking toevoegt.
Uw eigen knooppuntexemplaren maken
De XmlDocument klasse bevat methoden voor het maken van knooppunten. Wanneer een XML-bestand wordt geladen, worden deze methoden aangeroepen om de knooppunten te maken. U kunt deze methoden overschrijven zodat uw knooppuntexemplaren worden gemaakt wanneer een document wordt geladen. Als u de XmlElement klasse bijvoorbeeld hebt uitgebreid, neemt u de XmlDocument klasse over en overschrijft u de CreateElement methode.
In het volgende voorbeeld ziet u hoe u de CreateElement methode overschrijft om uw implementatie van de XmlElement klasse te retourneren.
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;
}
}
Een klasse uitbreiden
Als u een klasse wilt uitbreiden, moet u uw klas afleiden uit een van de bestaande DOM-klassen. U kunt vervolgens een van de virtuele methoden of eigenschappen in de basisklasse overschrijven of uw eigen methoden of eigenschappen toevoegen.
In het volgende voorbeeld wordt een nieuwe klasse gemaakt, waarmee de XmlElement klasse en de IXmlLineInfo interface worden geïmplementeerd. Er worden aanvullende methoden en eigenschappen gedefinieerd waarmee gebruikers regelgegevens kunnen verzamelen.
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.
Opmerking
In het volgende voorbeeld wordt het aantal elementen in een XML-document geteld:
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());
}
}
Invoer
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>
Uitvoer
Number of elements in book.xml: 3
Gebeurtenis-handler van knooppunt
De .NET Framework-implementatie van de DOM bevat ook een gebeurtenissysteem waarmee u gebeurtenissen kunt ontvangen en afhandelen wanneer knooppunten in een XML-document worden gewijzigd. Met behulp van de XmlNodeChangedEventHandler en klassen kunt u gebeurtenissen vastleggenNodeChanged
, , NodeChanging
, NodeInserted
, NodeInserting
NodeRemoved
en NodeRemoving
XmlNodeChangedEventArgs gebeurtenissen.
Het proces voor gebeurtenisafhandeling werkt precies hetzelfde in afgeleide klassen als in de oorspronkelijke DOM-klassen.
Zie Gebeurtenissen en XmlNodeChangedEventHandlervoor meer informatie over het afhandelen van knooppuntevenementen.
Standaardkenmerken en de methode CreateElement
Als u de CreateElement methode in een afgeleide klasse overschrijft, worden standaardkenmerken niet toegevoegd wanneer u nieuwe elementen maakt tijdens het bewerken van het document. Dit is slechts een probleem tijdens het bewerken. Omdat de methode verantwoordelijk is voor het CreateElement toevoegen van standaardkenmerken aan een XmlDocument, moet u deze functionaliteit codeeren in de CreateElement methode. Als u een XmlDocument met standaardkenmerken laadt, worden deze correct verwerkt. Zie Nieuwe kenmerken maken voor elementen in de DOM voor meer informatie over standaardkenmerken.