次の方法で共有


DOM の拡張

Microsoft .NET Framework には、XML ドキュメント オブジェクト モデル (DOM) の実装を提供するクラスの基本セットが含まれています。 XmlNodeとその派生クラスには、XML ドキュメントの内容と構造を移動、クエリ、および変更できるメソッドとプロパティが用意されています。

DOM を使用して XML コンテンツがメモリに読み込まれると、作成されたノードには、ノード名、ノードの種類などの情報が含まれます。 基底クラスで提供されていない特定のノード情報が必要になる場合があります。 たとえば、ノードの行番号と位置を確認できます。 この場合、既存の DOM クラスから新しいクラスを派生させ、追加の機能を追加できます。

新しいクラスを派生させる際には、次の 2 つの一般的なガイドラインがあります。

  • XmlNode クラスから派生しないようにすることをお勧めします。 代わりに、関心のあるノード型に対応するクラスからクラスを派生することをお勧めします。 たとえば、属性ノードに関する追加情報を返す場合は、 XmlAttribute クラスから派生させることができます。

  • ノードの作成方法を除き、関数をオーバーライドする場合は、常に基本バージョンの関数を呼び出し、さらに処理を追加することをお勧めします。

独自のノード インスタンスの作成

XmlDocument クラスには、ノードの作成方法が含まれています。 XML ファイルが読み込まれると、これらのメソッドが呼び出されてノードが作成されます。 ドキュメントの読み込み時にノード インスタンスが作成されるように、これらのメソッドをオーバーライドできます。 たとえば、 XmlElement クラスを拡張した場合は、 XmlDocument クラスを継承し、 CreateElement メソッドをオーバーライドします。

次の例では、 CreateElement メソッドをオーバーライドして、 XmlElement クラスの実装を返す方法を示します。

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;
    }
}

クラスの拡張

クラスを拡張するには、既存の DOM クラスの 1 つからクラスを派生させます。 その後、基底クラスの任意の仮想メソッドまたはプロパティをオーバーライドするか、独自のメソッドまたはプロパティを追加できます。

次の例では、 XmlElement クラスと IXmlLineInfo インターフェイスを実装する新しいクラスが作成されます。 ユーザーが行情報を収集できるようにする追加のメソッドとプロパティが定義されています。

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.

次の例では、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());

  }
}

インプット

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>

アウトプット

Number of elements in book.xml: 3

Node イベント ハンドラー

DOM の .NET Framework 実装には、XML ドキュメント内のノードが変更されたときにイベントを受信して処理できるようにするイベント システムも含まれています。 XmlNodeChangedEventHandlerクラスとXmlNodeChangedEventArgsクラスを使用して、NodeChangedNodeChangingNodeInsertedNodeInsertingNodeRemoved、およびNodeRemovingイベントをキャプチャできます。

イベント処理プロセスは、元の DOM クラスとまったく同じように派生クラスで動作します。

ノード イベント処理の詳細については、「 イベントXmlNodeChangedEventHandler」を参照してください。

既定の属性と CreateElement メソッド

派生クラスの CreateElement メソッドをオーバーライドする場合、ドキュメントの編集中に新しい要素を作成するときに、既定の属性は追加されません。 これは編集中にのみ問題になります。 CreateElement メソッドは既定の属性をXmlDocumentに追加する役割を担うため、CreateElement メソッドでこの機能をコーディングする必要があります。 既定の属性を含む XmlDocument を読み込む場合、それらは正しく処理されます。 既定の属性の詳細については、「DOM での 要素の新しい属性の作成」を参照してください。

こちらも参照ください