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ć NodeChangedzdarzenia , , NodeChangingNodeInserted, 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).

Zobacz też