Création de lecteur XML personnalisé
Les lecteurs XML personnalisés permettent à une application d'étendre soit XmlReader, soit XmlTextReader, ou de définir ses propres lecteurs personnalisés.
Exemple d'extension de XmlTextReader
L'exemple suivant montre comment étendre XmlTextReader afin de créer un lecteur qui convertit les attributs en éléments. La méthode Read substituée fournit la logique pour effectuer le suivi du type de nœud actuel, et, s'il s'agit d'un attribut, elle l'expose en tant que type de nœud d'élément à l'aide des propriétés XmlNodeType.Name et XmlNodeType.Value.
Option Explicit
Option Strict
Imports System
Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.XPath
Public Class AttrToElementReader
Inherits XmlTextReader
Private _ReadAttributes As Boolean = False
Private _ReadAttributeValue As Boolean = False
Private _AttributeName As String = String.Empty
Private _NodeType As XmlNodeType = XmlNodeType.None
Public Sub New(fileName As String)
MyBase.New(fileName)
MyBase.WhitespaceHandling = WhitespaceHandling.None
' Intentionally Empty
End Sub
Public Overrides Function Read() As Boolean
If Not _ReadAttributes Then
Dim baseRead As Boolean = MyBase.Read()
_ReadAttributes = baseRead And XmlNodeType.Element = MyBase.NodeType And 0 < MyBase.AttributeCount
Return baseRead
End If
'Read attribues;
If _ReadAttributeValue Then
_ReadAttributeValue = MyBase.ReadAttributeValue()
If Not _ReadAttributeValue Then
' End of attribute.
' End element.
_NodeType = XmlNodeType.EndElement
Else
_NodeType = XmlNodeType.None
End If
Return True
End If
_ReadAttributes = MyBase.MoveToNextAttribute()
If _ReadAttributes Then
_ReadAttributeValue = True
_NodeType = XmlNodeType.Element
_AttributeName = MyBase.Name
Return True
Else
_ReadAttributeValue = False
_NodeType = XmlNodeType.None
_AttributeName = String.Empty
Return Read()
End If
End Function
Public Overrides ReadOnly Property NodeType() As XmlNodeType
Get
If XmlNodeType.None = _NodeType Then
Return MyBase.NodeType
End If
Return _NodeType
End Get
End Property
Public Overrides ReadOnly Property Value() As String
Get
If XmlNodeType.None = _NodeType Then
Return MyBase.Value
End If
Return String.Empty
End Get
End Property
Public Overrides ReadOnly Property Name() As String
Get
If XmlNodeType.None = _NodeType Then
Return MyBase.Name
End If
Return _AttributeName
End Get
End Property
End Class 'AttrToElementReader
[C#]
using System;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.XPath;
public class AttrToElementReader: XmlTextReader {
private bool _ReadAttributes = false;
private bool _ReadAttributeValue = false;
private string _AttributeName = String.Empty;
private XmlNodeType _NodeType = XmlNodeType.None;
public AttrToElementReader(String fileName) : base(fileName) {
base.WhitespaceHandling = WhitespaceHandling.None;
// Intentionally Empty.
}
public override bool Read() {
if (!_ReadAttributes) {
bool baseRead = base.Read();
_ReadAttributes = (baseRead && XmlNodeType.Element == base.NodeType && 0 < base.AttributeCount);
return baseRead;
}
// Reading attribues;
if (_ReadAttributeValue) {
_ReadAttributeValue = base.ReadAttributeValue();
if (!_ReadAttributeValue) {
// End of attribute.
// End element.
_NodeType = XmlNodeType.EndElement;
}
else {
_NodeType = XmlNodeType.None;
}
return true;
}
_ReadAttributes = base.MoveToNextAttribute();
if (_ReadAttributes) {
_ReadAttributeValue = true;
_NodeType = XmlNodeType.Element;
_AttributeName = base.Name;
return true;
}
else {
_ReadAttributeValue = false;
_NodeType = XmlNodeType.None;
_AttributeName = String.Empty;
return Read();
}
}
public override XmlNodeType NodeType {
get {
if (XmlNodeType.None == _NodeType) {
return base.NodeType;
}
return _NodeType;
}
}
public override String Value {
get {
if (XmlNodeType.None == _NodeType) {
return base.Value;
}
return String.Empty;
}
}
public override String Name {
get {
if (XmlNodeType.None == _NodeType) {
return base.Name;
}
return _AttributeName;
}
}
}//AttrToElementReader
Chaînage des XmlReader
L'exemple suivant montre une classe d'implémentation nommée XmlReaderReader qui est utilisée en tant que classe pour chaîner les lecteurs XmlReader ensemble afin de fournir un flux de lecteurs en déléguant les appels. Ceci est utile lors de la création de lecteurs qui filtrent des entrées spécifiques et constitue une solution performante pour l'analyse spécifique sur du code XML.
Une classe dérivée de cette classe XmlReaderReader peut prendre n'importe quel XmlReader en tant qu'entrée. Dans l'exemple suivant, XmlCustomReader surcharge la méthode Read et ignore les nœuds d'élément price
antérieurs, les supprimant ainsi du flux.
' This sample demonstrate the ability to chain XmlReaders together by
' implementing an XmlReaderReader class which aggregates any given
' XmlReader and then delegates the calls to it
Namespace Test
Public Class MyApp
Public Shared Sub Main()
Dim reader As New XmlTextReader("books.xml")
Dim customreader As New XmlCustomReader(reader)
customreader.ReadandWrite()
End Sub
Class XmlCustomReader
Inherits XmlReaderReader
Public Sub New(reader As XmlTextReader)
MyBase.New(reader)
End Sub
Public Overrides Function Read() As Boolean
Dim result As Boolean
result = MyBase.Read()
Select Case MyBase.NodeType
Case XmlNodeType.Element
If MyBase.Name.Equals("price") Then
MyBase.Skip()
End If
Case Else
End Select
Return result
End Function
Public Sub ReadandWrite()
' Read each node in the tree.
While Read()
Select Case NodeType
Case XmlNodeType.Element
Console.Write(("<" + Name))
While MoveToNextAttribute()
Console.Write((" " + Name + "='" + Value + "'"))
End While
Console.Write(">")
Case XmlNodeType.Text
Console.Write(Value)
Case XmlNodeType.CDATA
Console.Write(Value)
Case XmlNodeType.ProcessingInstruction
Console.Write(("<?" + Name + " " + Value + "?>"))
Case XmlNodeType.Comment
Console.Write(("<!--" + Value + "-->"))
Case XmlNodeType.Document
Console.Write("<?xml version='1.0'?>")
Case XmlNodeType.Whitespace
Console.Write(Value)
Case XmlNodeType.SignificantWhitespace
Console.Write(Value)
Case XmlNodeType.EndElement
Console.Write(("</" + Name + ">"))
End Select
End While
End Sub
End Class
Public Class XmlReaderReader
Inherits XmlTextReader
Private _Reader As XmlTextReader
Public Sub New(reader As XmlTextReader)
_Reader = reader
End Sub
' XmlReader methods and properties.
Public Overrides ReadOnly Property NodeType() As XmlNodeType
Get
Return _Reader.NodeType
End Get
End Property
Public Overrides ReadOnly Property Name() As [String]
Get
Return _Reader.Name
End Get
End Property
Public Overrides ReadOnly Property LocalName() As [String]
Get
Return _Reader.LocalName
End Get
End Property
Public Overrides ReadOnly Property NamespaceURI() As [String]
Get
Return _Reader.NamespaceURI
End Get
End Property
Public Overrides ReadOnly Property Prefix() As [String]
Get
Return _Reader.Prefix
End Get
End Property
Public Overrides ReadOnly Property HasValue() As Boolean
Get
Return _Reader.HasValue
End Get
End Property
Public Overrides ReadOnly Property Value() As String
Get
Return _Reader.Value
End Get
End Property
Public Overrides ReadOnly Property Depth() As Integer
Get
Return _Reader.Depth
End Get
End Property
Public Overrides ReadOnly Property BaseURI() As String
Get
Return _Reader.BaseURI
End Get
End Property
Public Overrides ReadOnly Property IsEmptyElement() As Boolean
Get
Return _Reader.IsEmptyElement
End Get
End Property
Public Overrides ReadOnly Property IsDefault() As Boolean
Get
Return _Reader.IsDefault
End Get
End Property
Public Overrides ReadOnly Property QuoteChar() As Char
Get
Return _Reader.QuoteChar
End Get
End Property
Public Overrides ReadOnly Property XmlSpace() As XmlSpace
Get
Return _Reader.XmlSpace
End Get
End Property
Public Overrides ReadOnly Property XmlLang() As String
Get
Return _Reader.XmlLang
End Get
End Property
Public Overrides ReadOnly Property AttributeCount() As Integer
Get
Return _Reader.AttributeCount
End Get
End Property
Overloads Public Overrides Function GetAttribute(name As String) As String
Return _Reader.GetAttribute(name)
End Function
Overloads Public Overrides Function GetAttribute(name As String, namespaceURI As String) As String
Return _Reader.GetAttribute(name, namespaceURI)
End Function
Overloads Public Overrides Function GetAttribute(i As Integer) As String
Return _Reader.GetAttribute(i)
End Function
Default Public Overrides Overloads ReadOnly Property Item(i As Integer) As String
Get
Return _Reader(i)
End Get
End Property
Default Public Overrides Overloads ReadOnly Property Item(name As String) As String
Get
Return _Reader(name)
End Get
End Property
Default Public Overrides Overloads ReadOnly Property Item(name As String, namespaceURI As String) As String
Get
Return _Reader(name, namespaceURI)
End Get
End Property
Overloads Public Overrides Function MoveToAttribute(name As String) As Boolean
Return _Reader.MoveToAttribute(name)
End Function
Overloads Public Overrides Function MoveToAttribute(name As String, ns As String) As Boolean
Return _Reader.MoveToAttribute(name, ns)
End Function
Overloads Public Overrides Sub MoveToAttribute(i As Integer)
_Reader.MoveToAttribute(i)
End Sub
Public Overrides Function MoveToFirstAttribute() As Boolean
Return _Reader.MoveToFirstAttribute()
End Function
Public Overrides Function MoveToNextAttribute() As Boolean
Return _Reader.MoveToNextAttribute()
End Function
Public Overrides Function MoveToElement() As Boolean
Return _Reader.MoveToElement()
End Function
' This is the only place that needs to be changed.
Public Overrides Function Read() As Boolean
Return _Reader.Read()
End Function
Public Overrides ReadOnly Property EOF() As Boolean
Get
Return _Reader.EOF
End Get
End Property
Public Overrides Overloads Sub Close()
_Reader.Close()
End Sub
Public Overrides ReadOnly Property ReadState() As ReadState
Get
Return _Reader.ReadState
End Get
End Property
Public Overrides Function ReadString() As String
Return _Reader.ReadString()
End Function
Public Overrides Function ReadInnerXml() As String
Return _Reader.ReadInnerXml()
End Function
Public Overrides Function ReadOuterXml() As String
Return _Reader.ReadOuterXml()
End Function
Public Overrides ReadOnly Property NameTable() As XmlNameTable
Get
Return _Reader.NameTable
End Get
End Property
Public Overrides Function LookupNamespace(prefix As String) As String
Return _Reader.LookupNamespace(prefix)
End Function
Public Overrides Overloads Sub ResolveEntity()
_Reader.ResolveEntity()
End Sub
Public Overrides Function ReadAttributeValue() As Boolean
Return _Reader.ReadAttributeValue()
End Function
End Class
End Class
End Namespace
[C#]
using System;
using System.Xml;
// This sample demonstrate the ability to chain XmlReaders together by
// implementing an XmlReaderReader class which aggregates any given
// XmlReader and then delegates the calls to it.
namespace Test
{
public class MyApp
{
public static void Main()
{
XmlTextReader reader = new XmlTextReader("books.xml");
XmlChainingReader customreader = new XmlChainingReader(reader);
customreader.ReadandWrite();
}
class XmlChainingReader : XmlReaderReader
{
public XmlChainingReader (XmlReader reader) : base (reader)
{}
public override bool Read ()
{
bool result;
result = base.Read();
switch (base.NodeType)
{
case XmlNodeType.Element:
if (base.Name.Equals("price"))
base.Skip();
break;
default:
break;
}
return result;
}
public void ReadandWrite()
{
// Read each node in the tree.
while (Read())
{
switch (NodeType)
{
case XmlNodeType.Element:
Console.Write("<" + Name);
while (MoveToNextAttribute())
Console.Write(" " + Name + "='" + Value + "'");
Console.Write(">");
break;
case XmlNodeType.Text:
Console.Write(Value);
break;
case XmlNodeType.CDATA:
Console.Write(Value);
break;
case XmlNodeType.ProcessingInstruction:
Console.Write("<?" + Name + " " + Value + "?>");
break;
case XmlNodeType.Comment:
Console.Write("<!--" + Value + "-->");
break;
case XmlNodeType.Document:
Console.Write("<?xml version='1.0'?>");
break;
case XmlNodeType.Whitespace:
Console.Write(Value);
break;
case XmlNodeType.SignificantWhitespace:
Console.Write(Value);
break;
case XmlNodeType.EndElement:
Console.Write("</" + Name + ">");
break;
}
}
}
}
public class XmlReaderReader : XmlReader
{
XmlReader _Reader;
public XmlReaderReader (XmlReader reader )
{
_Reader = reader;
}
// XmlReader methods and properties.
public override XmlNodeType NodeType
{
get { return _Reader.NodeType; }
}
public override String Name
{
get { return _Reader.Name; }
}
public override String LocalName
{
get { return _Reader.LocalName; }
}
public override String NamespaceURI
{
get { return _Reader.NamespaceURI; }
}
public override String Prefix
{
get { return _Reader.Prefix; }
}
public override bool HasValue
{
get { return _Reader.HasValue; }
}
public override string Value
{
get { return _Reader.Value; }
}
public override int Depth
{
get { return _Reader.Depth; }
}
public override string BaseURI
{
get { return _Reader.BaseURI; }
}
public override bool IsEmptyElement
{
get { return _Reader.IsEmptyElement; }
}
public override bool IsDefault
{
get { return _Reader.IsDefault; }
}
public override char QuoteChar
{
get { return _Reader.QuoteChar; }
}
public override XmlSpace XmlSpace
{
get { return _Reader.XmlSpace; }
}
public override string XmlLang
{
get { return _Reader.XmlLang; }
}
public override int AttributeCount
{
get { return _Reader.AttributeCount; }
}
public override string GetAttribute(string name)
{
return _Reader.GetAttribute( name );
}
public override string GetAttribute(string name, string namespaceURI)
{
return _Reader.GetAttribute( name, namespaceURI );
}
public override string GetAttribute(int i)
{
return _Reader.GetAttribute( i );
}
public override string this [ int i ]
{
get { return _Reader[ i ]; }
}
public override string this [ string name ]
{
get { return _Reader[ name ]; }
}
public override string this [ string name,string namespaceURI ]
{
get { return _Reader[ name, namespaceURI ]; }
}
public override bool MoveToAttribute(string name)
{
return _Reader.MoveToAttribute( name );
}
public override bool MoveToAttribute(string name, string ns)
{
return _Reader.MoveToAttribute( name, ns );
}
public override void MoveToAttribute(int i)
{
_Reader.MoveToAttribute( i );
}
public override bool MoveToFirstAttribute()
{
return _Reader.MoveToFirstAttribute();
}
public override bool MoveToNextAttribute()
{
return _Reader.MoveToNextAttribute();
}
public override bool MoveToElement()
{
return _Reader.MoveToElement();
}
//
// This is the only place that needs to be changed.
//
public override bool Read()
{
return _Reader.Read();
}
public override bool EOF
{
get { return _Reader.EOF; }
}
public override void Close()
{
_Reader.Close();
}
public override ReadState ReadState
{
get { return _Reader.ReadState; }
}
public override string ReadString()
{
return _Reader.ReadString();
}
public override string ReadInnerXml()
{
return _Reader.ReadInnerXml();
}
public override string ReadOuterXml()
{
return _Reader.ReadOuterXml();
}
public override XmlNameTable NameTable
{
get { return _Reader.NameTable; }
}
public override string LookupNamespace(string prefix)
{
return _Reader.LookupNamespace( prefix );
}
public override void ResolveEntity()
{
_Reader.ResolveEntity();
}
public override bool ReadAttributeValue()
{
return _Reader.ReadAttributeValue();
}
}
}
}
Voir aussi
Lecture de XML avec XmlReader | Lecture de données XML avec XmlTextReader | Lecture d'arborescences de nœuds avec XmlNodeReader | Validation de code XML avec XmlValidatingReader | XmlReader, classe | XmlReader, membres | XmlNodeReader, classe | XmlNodeReader, membres | XmlTextReader, classe | XmlTextReader, membres | XmlValidatingReader, classe | XmlValidatingReader