Rozszerzanie modelu DOM
Program Microsoft .NET Framework zawiera podstawowy zestaw klas, który zapewnia implementację modelu DOM (XML Document Object Model). Klasy XmlNodepochodne , i , udostępnia metody i właściwości, które umożliwiają nawigowanie, wykonywanie zapytań i modyfikowanie zawartości i struktury dokumentu XML.
Gdy zawartość XML jest ładowana do pamięci przy użyciu modelu DOM, utworzone węzły zawierają informacje, takie jak nazwa węzła, typ węzła itd. Mogą wystąpić sytuacje, w których wymagane są określone informacje o węźle, które nie są podane w klasach bazowych. Możesz na przykład zobaczyć numer wiersza i położenie węzła. W takim przypadku można utworzyć nowe klasy z istniejących klas DOM i dodać dodatkowe funkcje.
Istnieją dwa ogólne wytyczne dotyczące wyprowadzania nowych klas:
Zaleca się, aby nigdy nie pochodzić z XmlNode klasy . Zamiast tego zaleca się, aby klasy pochodzą z klasy odpowiadającej typowi węzła, który cię interesuje. Jeśli na przykład chcesz zwrócić dodatkowe informacje o węzłach atrybutów, możesz uzyskać informacje z XmlAttribute klasy .
Z wyjątkiem metod tworzenia węzłów zaleca się, aby podczas zastępowania funkcji zawsze wywoływać podstawową wersję funkcji, a następnie dodać dodatkowe przetwarzanie.
Tworzenie własnych wystąpień węzłów
Klasa XmlDocument zawiera metody tworzenia węzłów. Po załadowaniu pliku XML te metody są wywoływane w celu utworzenia węzłów. Te metody można zastąpić tak, aby wystąpienia węzłów były tworzone podczas ładowania dokumentu. Jeśli na przykład rozszerzono klasę, odziedziczysz klasę XmlElementXmlDocument i zastąpisz metodę CreateElement .
W poniższym przykładzie pokazano, jak zastąpić metodę CreateElement w celu zwrócenia implementacji XmlElement klasy.
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;
}
}
Rozszerzanie klasy
Aby rozszerzyć klasę, utwórz klasę z jednej z istniejących klas DOM. Następnie można zastąpić dowolne metody wirtualne lub właściwości w klasie bazowej lub dodać własne.
W poniższym przykładzie zostanie utworzona nowa klasa, która implementuje klasę XmlElementIXmlLineInfo i interfejs. Zdefiniowano dodatkowe metody i właściwości, które umożliwiają użytkownikom zbieranie informacji o wierszu.
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.
Przykład
Poniższy przykład zlicza liczbę elementów w dokumencie 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());
}
}
Dane wejściowe
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>
Wyjście
Number of elements in book.xml: 3
Program obsługi zdarzeń węzła
Implementacja platformy .NET Framework modelu DOM obejmuje również system zdarzeń, który umożliwia odbieranie i obsługę zdarzeń w przypadku zmiany węzłów w dokumencie XML. XmlNodeChangedEventHandler Za pomocą klas i XmlNodeChangedEventArgs można przechwytywać NodeChanged
zdarzenia , , NodeChanging
NodeInserted
, NodeInserting
, NodeRemoved
, i NodeRemoving
.
Proces obsługi zdarzeń działa dokładnie tak samo w klasach pochodnych, jak w oryginalnych klasach DOM.
Aby uzyskać więcej informacji na temat obsługi zdarzeń węzła, zobacz Zdarzenia i XmlNodeChangedEventHandler.
Atrybuty domyślne i metoda CreateElement
Jeśli zastępujesz metodę CreateElement w klasie pochodnej, atrybuty domyślne nie są dodawane podczas tworzenia nowych elementów podczas edytowania dokumentu. Jest to problem tylko podczas edytowania. CreateElement Ponieważ metoda jest odpowiedzialna za dodawanie atrybutów domyślnych do XmlDocumentklasy , należy za kodować tę funkcję w metodzie CreateElement . Jeśli ładujesz element XmlDocument zawierający atrybuty domyślne, zostaną one poprawnie obsłużone. Aby uzyskać więcej informacji na temat atrybutów domyślnych, zobacz Creating New Attributes for Elements in the DOM (Tworzenie nowych atrybutów dla elementów w modelu DOM).