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クラスを使用して、NodeChanged
、NodeChanging
、NodeInserted
、NodeInserting
、NodeRemoved
、およびNodeRemoving
イベントをキャプチャできます。
イベント処理プロセスは、元の DOM クラスとまったく同じように派生クラスで動作します。
ノード イベント処理の詳細については、「 イベント と XmlNodeChangedEventHandler」を参照してください。
既定の属性と CreateElement メソッド
派生クラスの CreateElement メソッドをオーバーライドする場合、ドキュメントの編集中に新しい要素を作成するときに、既定の属性は追加されません。 これは編集中にのみ問題になります。 CreateElement メソッドは既定の属性をXmlDocumentに追加する役割を担うため、CreateElement メソッドでこの機能をコーディングする必要があります。 既定の属性を含む XmlDocument を読み込む場合、それらは正しく処理されます。 既定の属性の詳細については、「DOM での 要素の新しい属性の作成」を参照してください。
こちらも参照ください
.NET