Klasse System.Xml.XmlReader

Notitie

In dit artikel vindt u aanvullende opmerkingen in de referentiedocumentatie voor deze API.

XmlReader biedt alleen-lezentoegang tot XML-gegevens in een document of stream. Deze klasse voldoet aan de W3C Extensible Markup Language (XML) 1.0 (vierde editie) en de naamruimten in aanbevelingen voor XML 1.0 (derde editie).

XmlReader met methoden kunt u door XML-gegevens navigeren en de inhoud van een knooppunt lezen. De eigenschappen van de klasse weerspiegelen de waarde van het huidige knooppunt, waar de lezer zich bevindt. De ReadState eigenschapswaarde geeft de huidige status van de XML-lezer aan. De eigenschap wordt bijvoorbeeld ingesteld op ReadState.Initial basis van de XmlReader.Read methode en ReadState.Closed door de XmlReader.Close methode. XmlReader biedt ook controles en validatie van gegevensconformantie op basis van een DTD of schema.

XmlReader gebruikt een pull-model om gegevens op te halen. Dit model:

  • Vereenvoudigt staatsbeheer door een natuurlijke, top-down procedurele verfijning.
  • Ondersteunt meerdere invoerstromen en lagen.
  • Stelt de client in staat om de parser een buffer te geven waarin de tekenreeks rechtstreeks is geschreven, en voorkomt zo de noodzaak van een extra tekenreekskopie.
  • Ondersteunt selectieve verwerking. De client kan items overslaan en verwerken die van belang zijn voor de toepassing. U kunt ook vooraf eigenschappen instellen om te beheren hoe de XML-stroom wordt verwerkt (bijvoorbeeld normalisatie).

Een XML-lezer maken

Gebruik de Create methode om een XmlReader exemplaar te maken.

Hoewel .NET concrete implementaties van de XmlReader klasse biedt, zoals de XmlTextReader, XmlNodeReaderen de XmlValidatingReader klassen, raden we u aan de gespecialiseerde klassen alleen in deze scenario's te gebruiken:

  • Als u een XML DOM-substructuur van een XmlNode object wilt lezen, gebruikt u de XmlNodeReader klasse. (Deze klasse biedt echter geen ondersteuning voor DTD- of schemavalidatie.)
  • Als u entiteiten op aanvraag moet uitbreiden, wilt u de tekstinhoud niet normaliseren of wilt u niet dat standaardkenmerken worden geretourneerd, gebruikt u de XmlTextReader klasse.

Als u de set functies wilt opgeven die u wilt inschakelen voor de XML-lezer, geeft u een System.Xml.XmlReaderSettings object door aan de Create methode. U kunt één System.Xml.XmlReaderSettings object gebruiken om meerdere lezers met dezelfde functionaliteit te maken of het System.Xml.XmlReaderSettings object te wijzigen om een nieuwe lezer te maken met een andere set functies. U kunt ook eenvoudig functies toevoegen aan een bestaande lezer.

Als u geen object gebruikt System.Xml.XmlReaderSettings , worden standaardinstellingen gebruikt. Zie de Create referentiepagina voor meer informatie.

XmlReader genereert een XmlException op XML-parseringsfouten. Nadat een uitzondering is gegenereerd, is de status van de lezer niet voorspelbaar. Het gerapporteerde knooppunttype kan bijvoorbeeld afwijken van het werkelijke knooppunttype van het huidige knooppunt. Gebruik de ReadState eigenschap om te controleren of de lezer de foutstatus heeft.

XML-gegevens valideren

Als u de structuur van een XML-document en de bijbehorende elementrelaties, gegevenstypen en inhoudsbeperkingen wilt definiëren, gebruikt u een DTD-schema (documenttypedefinitie) of XSD-schema (XML Schema Definition Language). Een XML-document wordt beschouwd als goed gevormd als het voldoet aan alle syntactische vereisten die zijn gedefinieerd door de W3C XML 1.0-aanbeveling. Het wordt als geldig beschouwd als deze goed is gevormd en voldoet ook aan de beperkingen die zijn gedefinieerd door de DTD of het schema. (Zie het W3C XML-schema deel 1: Structuren en het W3C XML-schema deel 2: aanbevelingen voor gegevenstypen .) Hoewel alle geldige XML-documenten goed zijn opgemaakt, zijn niet alle goed opgemaakte XML-documenten geldig.

U kunt de gegevens valideren op basis van een DTD, een inline XSD-schema of een XSD-schema dat is opgeslagen in een XmlSchemaSet object (een cache). Deze scenario's worden beschreven op de Create referentiepagina. XmlReader biedt geen ondersteuning voor XML-Data XDR-schemavalidatie (Reduced).

U gebruikt de volgende instellingen voor de XmlReaderSettings klasse om op te geven welk type validatie, indien van toepassing, het XmlReader exemplaar ondersteunt.

XmlReaderSettings Dit lid gebruiken Specificeren
eigenschap DtdProcessing Of DTD-verwerking is toegestaan. De standaardinstelling is om DTD-verwerking niet toe te staan.
eigenschap ValidationType Of de lezer gegevens moet valideren en welk type validatie moet worden uitgevoerd (DTD of schema). De standaardwaarde is geen gegevensvalidatie.
ValidationEventHandler gebeurtenis Een eventhandler voor het ontvangen van informatie over validatiegebeurtenissen. Als er geen gebeurtenis-handler wordt opgegeven, wordt er een XmlException gegenereerd op de eerste validatiefout.
eigenschap ValidationFlags Aanvullende validatieopties via de XmlSchemaValidationFlags opsommingsleden:

- AllowXmlAttributes-- XML-kenmerken (xml:*) in exemplaardocumenten toestaan, zelfs wanneer ze niet zijn gedefinieerd in het schema. De kenmerken worden gevalideerd op basis van hun gegevenstype. Zie de XmlSchemaValidationFlags referentiepagina voor de instelling die in specifieke scenario's moet worden gebruikt. (Standaard uitgeschakeld.)
- ProcessIdentityConstraints --Procesidentiteitsbeperkingen (xs:ID, xs:IDREF, xs:key, xs:keyref, ) xs:uniquedie zijn aangetroffen tijdens de validatie. (Standaard ingeschakeld.)
- ProcessSchemaLocation --Processchema's die zijn opgegeven door het xsi:schemaLocation of xsi:noNamespaceSchemaLocation kenmerk. (Standaard ingeschakeld.)
- ProcessInlineSchema-- Inline XML-schema's verwerken tijdens validatie. (Standaard uitgeschakeld.)
- ReportValidationWarnings--Rapporteer gebeurtenissen als er een validatiewaarschuwing optreedt. Er wordt doorgaans een waarschuwing gegeven wanneer er geen DTD- of XML-schema is om een bepaald element of kenmerk te valideren. De ValidationEventHandler wordt gebruikt voor meldingen. (Standaard uitgeschakeld.)
Schemas De XmlSchemaSet te gebruiken voor validatie.
eigenschap XmlResolver De XmlResolver oplossing voor het oplossen en openen van externe resources. Dit kunnen externe entiteiten zijn, zoals DTD en schema's, en alle xs:include elementen in xs:import het XML-schema. Als u geen XmlResolver opgeeft, gebruikt de XmlReader een standaard XmlUrlResolver zonder gebruikersgegevens.

Gegevensconformance

XML-lezers die door de Create methode worden gemaakt, voldoen standaard aan de volgende nalevingsvereisten:

  • Nieuwe regels en kenmerkwaarden worden genormaliseerd volgens de W3C XML 1.0-aanbeveling.

  • Alle entiteiten worden automatisch uitgebreid.

  • Standaardkenmerken die zijn gedeclareerd in de definitie van het documenttype, worden altijd toegevoegd, zelfs wanneer de lezer niet valideert.

  • Declaratie van XML-voorvoegsel dat is toegewezen aan de juiste XML-naamruimte-URI is toegestaan.

  • De notatienamen in één NotationType kenmerkdeclaratie en NmTokens in één Enumeration kenmerkdeclaratie zijn verschillend.

Gebruik deze XmlReaderSettings eigenschappen om het type nalevingscontroles op te geven dat u wilt inschakelen:

XmlReaderSettings Deze eigenschap gebruiken Tot Verstek
eigenschap CheckCharacters Schakel controles voor het volgende in of uit:

- Tekens vallen binnen het bereik van juridische XML-tekens, zoals gedefinieerd in de sectie 2.2 Tekens van de W3C XML 1.0-aanbeveling.
- Alle XML-namen zijn geldig, zoals gedefinieerd in de sectie 2.3 Algemene Syntactische constructies van de W3C XML 1.0-aanbeveling.

Wanneer deze eigenschap is ingesteld op true (standaard), wordt er een XmlException uitzondering gegenereerd als het XML-bestand ongeldige tekens of ongeldige XML-namen bevat (bijvoorbeeld een elementnaam begint met een getal).
Teken- en naamcontrole is ingeschakeld.

Het instellen van CheckCharacters op false schakelt de controle op tekens voor tekenentiteitverwijzingen uit. Als de lezer tekstgegevens verwerkt, wordt er altijd gecontroleerd of XML-namen geldig zijn, ongeacht deze instelling. Notitie: Voor de XML 1.0-aanbeveling is overeenstemming op documentniveau vereist wanneer er een DTD aanwezig is. Als de lezer is geconfigureerd voor de ondersteuning van ConformanceLevel.Fragment, maar de XML-gegevens een documenttype definitie (DTD) bevatten, wordt er een XmlException gegenereerd.
eigenschap ConformanceLevel Kies het nalevingsniveau dat u wilt afdwingen:

- Document. Voldoet aan de regels voor een goed opgemaakt XML 1.0-document.
- Fragment. Voldoet aan de regels voor een goed opgemaakt documentfragment dat kan worden gebruikt als een externe geparseerde entiteit.
- Auto. Voldoet aan het niveau dat door de lezer is bepaald.

Als de gegevens niet in overeenstemming zijn, wordt er een XmlException uitzondering gegenereerd.
Document

Het huidige knooppunt is het XML-knooppunt waarop de XML-lezer zich momenteel bevindt. Alle XmlReader methoden voeren bewerkingen uit met betrekking tot dit knooppunt en alle XmlReader eigenschappen weerspiegelen de waarde van het huidige knooppunt.

Met de volgende methoden kunt u eenvoudig door knooppunten navigeren en gegevens parseren.

Gebruik deze XmlReaderSettings methode Tot
Read Lees het eerste knooppunt en doorloop de stream, één knooppunt per keer. Dergelijke aanroepen worden doorgaans binnen een while lus uitgevoerd.

Gebruik de NodeType eigenschap om het type op te halen (bijvoorbeeld kenmerk, opmerking, element, enzovoort) van het huidige knooppunt.
Skip Sla de kinderen van het huidige knooppunt over en ga door naar het volgende knooppunt.
MoveToContent en MoveToContentAsync Sla niet-inhoudsknooppunten over en ga naar het volgende inhoudsknooppunt of naar het einde van het bestand.

Niet-inhoudsknooppunten zijn onder andere ProcessingInstruction, DocumentType, Comment, Whitespaceen SignificantWhitespace.

Inhoudsknooppunten bevatten niet-witruimtetekst, CDATA, EntityReference en EndEntity.
ReadSubtree Lees een element en alle onderliggende elementen en retourneer een nieuwe XmlReader instantie die is ingesteld op ReadState.Initial.

Deze methode is handig voor het maken van grenzen rond XML-elementen; Als u bijvoorbeeld gegevens wilt doorgeven aan een ander onderdeel voor verwerking en u wilt beperken hoeveel van uw gegevens het onderdeel kan openen.

Zie de XmlReader.Read referentiepagina voor een voorbeeld van het navigeren door een tekststroom, waarbij u één knooppunt tegelijk bekijkt en het type van elk knooppunt weergeeft.

In de volgende secties wordt beschreven hoe u specifieke typen gegevens kunt lezen, zoals elementen, kenmerken en getypte gegevens.

XML-elementen lezen

De volgende tabel bevat de methoden en eigenschappen die de XmlReader klasse biedt voor verwerkingselementen. Nadat het XmlReader element op een element is positioneerd, geven de eigenschappen van het knooppunt, zoals Name, de elementwaarden weer. Naast de hieronder beschreven leden kunnen alle algemene methoden en eigenschappen van de XmlReader klasse ook worden gebruikt om elementen te verwerken. U kunt bijvoorbeeld de ReadInnerXml methode gebruiken om de inhoud van een element te lezen.

Notitie

Zie sectie 3.1 van de W3C XML 1.0-aanbeveling voor definities van begintags, eindtags en lege elementtags.

XmlReader Dit lid gebruiken Tot
IsStartElement methode Controleer of het huidige knooppunt een starttag of een lege elementtag is.
ReadStartElement methode Controleer of het huidige knooppunt een element is en ga naar het volgende knooppunt (aanroepen IsStartElement gevolgd door Read).
ReadEndElement methode Controleer of het huidige knooppunt een eindtabel is en laat de lezer naar het volgende knooppunt vooruitgaan.
ReadElementString methode Een element dat alleen tekst bevat lezen.
ReadToDescendant methode Laat de XML-lezer verdergaan naar het volgende kindelement met de opgegeven naam.
ReadToNextSibling methode Verplaats de XML-lezer naar het volgende element op hetzelfde niveau dat de opgegeven naam heeft.
eigenschap IsEmptyElement Controleer of huidig element een eind-elementtag heeft. Voorbeeld:

- <item num="123"/> (IsEmptyElement is true.)
- <item num="123"> </item> (IsEmptyElement is false, hoewel de inhoud van het element leeg is.)

Zie de ReadString methode voor een voorbeeld van het lezen van de tekstinhoud van elementen. In het volgende voorbeeld worden elementen verwerkt met behulp van een while lus.

while (reader.Read()) {
  if (reader.IsStartElement()) {
    if (reader.IsEmptyElement)
                {
                    Console.WriteLine($"<{reader.Name}/>");
                }
                else {
      Console.Write("<{0}> ", reader.Name);
      reader.Read(); // Read the start tag.
      if (reader.IsStartElement())  // Handle nested elements.
        Console.Write("\r\n<{0}>", reader.Name);
      Console.WriteLine(reader.ReadString());  //Read the text content of the element.
    }
  }
}
While reader.Read()
  If reader.IsStartElement() Then
    If reader.IsEmptyElement Then
      Console.WriteLine("<{0}/>", reader.Name)
    Else
      Console.Write("<{0}> ", reader.Name)
      reader.Read() ' Read the start tag.
      If reader.IsStartElement() Then ' Handle nested elements.
        Console.Write(vbCr + vbLf + "<{0}>", reader.Name)
      End If
      Console.WriteLine(reader.ReadString()) 'Read the text content of the element.
    End If
  End If
End While

XML-kenmerken lezen

XML-kenmerken worden meestal gevonden op elementen, maar ze zijn ook toegestaan op XML-declaratie- en documenttypeknooppunten.

Wanneer u zich op een elementknooppunt bevindt, kunt u met de MoveToAttribute methode de kenmerklijst van het element doorlopen. Houd er rekening mee dat nadat MoveToAttribute het is aangeroepen, knooppunteigenschappen zoals Name, NamespaceURIen Prefix de eigenschappen van dat kenmerk weerspiegelen, niet de eigenschappen van het element waartoe het kenmerk behoort.

De XmlReader klasse biedt deze methoden en eigenschappen voor het lezen en verwerken van kenmerken op elementen.

XmlReader Dit lid gebruiken Tot
eigenschap HasAttributes Controleer of het huidige knooppunt kenmerken heeft.
eigenschap AttributeCount Het aantal kenmerken op het huidige element ophalen.
MoveToFirstAttribute methode Naar het eerste kenmerk in een element gaan.
MoveToNextAttribute methode Naar het volgende kenmerk in een element gaan.
MoveToAttribute methode Naar een opgegeven kenmerk gaan.
GetAttribute methode of Item[Int32] eigenschap Haal de waarde van een opgegeven kenmerk op.
eigenschap IsDefault Controleer of het huidige knooppunt een kenmerk is dat is gegenereerd op basis van de standaardwaarde die is gedefinieerd in de DTD of het schema.
MoveToElement methode Naar het element gaan dat eigenaar is van het huidige kenmerk. Gebruik deze methode om terug te keren naar een element nadat u de kenmerken ervan hebt doorlopen.
ReadAttributeValue methode Parseert de kenmerkwaarde in een of meer Text, EntityReferenceof EndEntity knooppunten.

Een van de algemene XmlReader methoden en eigenschappen kan ook worden gebruikt om kenmerken te verwerken. Bijvoorbeeld, nadat het XmlReader op een attribuut is geplaatst, geven de Name en Value eigenschappen de waarden van het attribuut weer. U kunt ook een van de inhoudsmethoden Read gebruiken om de waarde van het kenmerk op te halen.

In dit voorbeeld wordt de AttributeCount eigenschap gebruikt om door alle kenmerken van een element te navigeren.

// Display all attributes.
if (reader.HasAttributes) {
  Console.WriteLine("Attributes of <" + reader.Name + ">");
  for (int i = 0; i < reader.AttributeCount; i++) {
    Console.WriteLine($"  {reader[i]}");
  }
  // Move the reader back to the element node.
  reader.MoveToElement();
}
' Display all attributes.
If reader.HasAttributes Then
  Console.WriteLine("Attributes of <" + reader.Name + ">")
  Dim i As Integer
  For i = 0 To (reader.AttributeCount - 1)
    Console.WriteLine("  {0}", reader(i))
  Next i
  ' Move the reader back to the element node.
  reader.MoveToElement() 
End If

In dit voorbeeld wordt de MoveToNextAttribute methode in een while lus gebruikt om door de kenmerken te navigeren.

if (reader.HasAttributes) {
  Console.WriteLine("Attributes of <" + reader.Name + ">");
  while (reader.MoveToNextAttribute()) {
    Console.WriteLine($" {reader.Name}={reader.Value}");
  }
  // Move the reader back to the element node.
  reader.MoveToElement();
}
If reader.HasAttributes Then
  Console.WriteLine("Attributes of <" + reader.Name + ">")
  While reader.MoveToNextAttribute()
    Console.WriteLine(" {0}={1}", reader.Name, reader.Value)
  End While
  ' Move the reader back to the element node.
  reader.MoveToElement()
End If

Kenmerken lezen op XML-declaratieknooppunten

Wanneer de XML-lezer op een XML-declaratieknooppunt wordt weergegeven, retourneert de Value eigenschap de versie-, zelfstandige en coderingsgegevens als één tekenreeks. XmlReader objecten die zijn gemaakt door de Create methode, de XmlTextReader klasse en de XmlValidatingReader klasse maken de versie, zelfstandige en coderingsitems beschikbaar als kenmerken.

Kenmerken lezen op documenttypeknooppunten

Wanneer de XML-lezer op een documenttypeknooppunt wordt geplaatst, kunnen de GetAttribute methode en Item[Int32] eigenschap worden gebruikt om de waarden voor de letterlijke waarden SYSTEM en PUBLIC te retourneren. Als u bijvoorbeeld aanroept reader.GetAttribute("PUBLIC") , wordt de openbare waarde geretourneerd.

Kenmerken voor het verwerken van instructieknooppunten lezen

Wanneer de XmlReader positie is op een verwerkingsinstructieknooppunt, retourneert de Value eigenschap de volledige tekstinhoud. Items in het verwerkingsinstructieknooppunt worden niet behandeld als kenmerken. Ze kunnen niet worden gelezen met de GetAttribute of MoveToAttribute methode.

XML-inhoud lezen

De klasse XmlReader bevat de volgende leden die inhoud uit een XML-bestand lezen en de inhoud retourneren als tekenreekswaarden. (Zie Converteren naar CLR-typen om CLR-typen te retourneren.)

XmlReader Dit lid gebruiken Tot
eigenschap Value Haal de tekstinhoud van het huidige knooppunt op. De geretourneerde waarde is afhankelijk van het knooppunttype; zie de Value referentiepagina voor meer informatie.
ReadString methode Haal de inhoud van een element of tekstknooppunt op als een tekenreeks. Deze methode stopt bij het verwerken van instructies en opmerkingen.

Zie de ReadString referentiepagina voor meer informatie over hoe deze methode specifieke knooppunttypen verwerkt.
methoden voor ReadInnerXml en ReadInnerXmlAsync Haal alle inhoud van het huidige knooppunt op, inclusief de markeringen, maar exclusief begin- en eindtags. Bijvoorbeeld, zoals:

<node>this<child id="123"/></node>

ReadInnerXml retourneert:

this<child id="123"/>
methoden voor ReadOuterXml en ReadOuterXmlAsync Haal alle inhoud van het huidige knooppunt en zijn kinderen op, inclusief opmaak en begin-/eindtags. Bijvoorbeeld, zoals:

<node>this<child id="123"/></node>

ReadOuterXml retourneert:

<node>this<child id="123"/></node>

Converteren naar CLR-typen

U kunt de leden van de XmlReader klasse (vermeld in de volgende tabel) gebruiken om XML-gegevens te lezen en waarden te retourneren als CLR-typen (Common Language Runtime) in plaats van tekenreeksen. Met deze leden kunt u waarden ophalen in de weergave die het meest geschikt is voor uw coderingstaak zonder dat u tekenreekswaarden handmatig hoeft te parseren of converteren.

  • De methoden ReadElementContentAs kunnen alleen worden aangeroepen op elementknooppunttypen. Deze methoden kunnen niet worden gebruikt op elementen die kindelementen bevatten of als ze gemengde inhoud hebben. Wanneer het XmlReader object wordt aangeroepen, wordt de starttag gelezen, wordt de inhoud van het element gelezen en wordt dan het eindelementtag gepasseerd. Verwerkingsinstructies en opmerkingen worden genegeerd en entiteiten worden uitgebreid.

  • De methoden ReadContentAs lezen de tekstinhoud op de huidige positie van de lezer en als er geen schema- of gegevenstypegegevens aan de XML-gegevens zijn gekoppeld, converteert u de tekstinhoud naar het aangevraagde retourtype. Tekst, witruimte, significante witruimte en CDATA-secties worden samengevoegd. Opmerkingen en verwerkingsinstructies worden overgeslagen en entiteitsverwijzingen worden automatisch opgelost.

De XmlReader klasse maakt gebruik van de regels die zijn gedefinieerd door het W3C XML-schema deel 2: aanbeveling voor gegevenstypen .

Gebruik deze XmlReader methode Om dit CLR-type terug te geven
ReadContentAsBoolean en ReadElementContentAsBoolean Boolean
ReadContentAsDateTime en ReadElementContentAsDateTime DateTime
ReadContentAsDouble en ReadElementContentAsDouble Double
ReadContentAsLong en ReadElementContentAsLong Int64
ReadContentAsInt en ReadElementContentAsInt Int32
ReadContentAsString en ReadElementContentAsString String
ReadContentAs en ReadElementContentAs Het type dat u opgeeft met de returnType parameter
ReadContentAsObject en ReadElementContentAsObject Het meest geschikte type, zoals opgegeven door de XmlReader.ValueType eigenschap. Zie Typeondersteuning in de System.Xml-klassen voor toewijzingsinformatie.

Als een element niet eenvoudig kan worden geconverteerd naar een CLR-type vanwege de indeling, kunt u een schematoewijzing gebruiken om een geslaagde conversie te garanderen. In het volgende voorbeeld wordt een XSD-bestand gebruikt om het hire-date element te converteren naar het xs:date type en vervolgens de ReadElementContentAsDateTime methode gebruikt om het element als object DateTime te retourneren.

Invoer (hireDate.xml):

<employee xmlns="urn:empl-hire">
    <ID>12365</ID>
    <hire-date>2003-01-08</hire-date>
    <title>Accountant</title>
</employee>

Schema (hireDate.xsd):

<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="urn:empl-hire" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="employee">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ID" type="xs:unsignedShort" />
        <xs:element name="hire-date" type="xs:date" />
        <xs:element name="title" type="xs:string" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Code:

// Create a validating XmlReader object. The schema
// provides the necessary type information.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas.Add("urn:empl-hire", "hireDate.xsd");
using (XmlReader reader = XmlReader.Create("hireDate.xml", settings)) {

  // Move to the hire-date element.
  reader.MoveToContent();
  reader.ReadToDescendant("hire-date");

  // Return the hire-date as a DateTime object.
  DateTime hireDate = reader.ReadElementContentAsDateTime();
  Console.WriteLine($"Six Month Review Date: {hireDate.AddMonths(6)}");
}
' Create a validating XmlReader object. The schema 
' provides the necessary type information.
Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.ValidationType = ValidationType.Schema
settings.Schemas.Add("urn:empl-hire", "hireDate.xsd")
Using reader As XmlReader = XmlReader.Create("hireDate.xml", settings) 
  ' Move to the hire-date element.
  reader.MoveToContent()
  reader.ReadToDescendant("hire-date")

  ' Return the hire-date as a DateTime object.
  Dim hireDate As DateTime = reader.ReadElementContentAsDateTime()
  Console.WriteLine("Six Month Review Date: {0}", hireDate.AddMonths(6))
End Using

Uitvoer:

Six Month Review Date:  7/8/2003 12:00:00 AM

Asynchroon programmeren

XmlReader De meeste methoden hebben asynchrone tegenhangers die 'Async' aan het einde van hun methodenamen hebben. Bijvoorbeeld, het asynchrone equivalent van ReadContentAsObject is ReadContentAsObjectAsync.

De volgende methoden kunnen worden gebruikt met asynchrone methodeaanroepen:

In de volgende secties wordt asynchroon gebruik beschreven voor methoden die geen asynchrone tegenhangers hebben.

Methode ReadStartElement

public static async Task ReadStartElementAsync(this XmlReader reader, string localname, string ns)
{
    if (await reader.MoveToContentAsync() != XmlNodeType.Element)
    {
        throw new InvalidOperationException(reader.NodeType.ToString() + " is an invalid XmlNodeType");
    }
    if ((reader.LocalName == localname) && (reader.NamespaceURI == ns))
    {
        await reader.ReadAsync();
    }
    else
    {
        throw new InvalidOperationException("localName or namespace doesn’t match");
    }
}
<Extension()>
Public Async Function ReadStartElementAsync(reader As XmlReader, localname As String, ns As String) As Task
    If (Await reader.MoveToContentAsync() <> XmlNodeType.Element) Then
        Throw New InvalidOperationException(reader.NodeType.ToString() + " is an invalid XmlNodeType")
    End If

    If ((reader.LocalName = localname) And (reader.NamespaceURI = ns)) Then
        Await reader.ReadAsync()
    Else
        Throw New InvalidOperationException("localName or namespace doesn’t match")
    End If
End Function

Methode ReadEndElement

public static async Task ReadEndElementAsync(this XmlReader reader)
{
    if (await reader.MoveToContentAsync() != XmlNodeType.EndElement)
    {
        throw new InvalidOperationException();
    }
    await reader.ReadAsync();
}
<Extension()>
Public Async Function ReadEndElementAsync(reader As XmlReader) As task
    If (Await reader.MoveToContentAsync() <> XmlNodeType.EndElement) Then
        Throw New InvalidOperationException()
    End If
    Await reader.ReadAsync()
End Function

Methode ReadToNextSibling

public static async Task<bool> ReadToNextSiblingAsync(this XmlReader reader, string localName, string namespaceURI)
{
    if (localName == null || localName.Length == 0)
    {
        throw new ArgumentException("localName is empty or null");
    }
    if (namespaceURI == null)
    {
        throw new ArgumentNullException("namespaceURI");
    }

    // atomize local name and namespace
    localName = reader.NameTable.Add(localName);
    namespaceURI = reader.NameTable.Add(namespaceURI);

    // find the next sibling
    XmlNodeType nt;
    do
    {
        await reader.SkipAsync();
        if (reader.ReadState != ReadState.Interactive)
            break;
        nt = reader.NodeType;
        if (nt == XmlNodeType.Element &&
             ((object)localName == (object)reader.LocalName) &&
             ((object)namespaceURI ==(object)reader.NamespaceURI))
        {
            return true;
        }
    } while (nt != XmlNodeType.EndElement && !reader.EOF);
    
    return false;
}
<Extension()>
Public Async Function ReadToNextSiblingAsync(reader As XmlReader, localName As String, namespaceURI As String) As Task(Of Boolean)
    If (localName = Nothing Or localName.Length = 0) Then
        Throw New ArgumentException("localName is empty or null")
    End If

    If (namespaceURI = Nothing) Then
        Throw New ArgumentNullException("namespaceURI")
    End If

    ' atomize local name and namespace
    localName = reader.NameTable.Add(localName)
    namespaceURI = reader.NameTable.Add(namespaceURI)

    ' find the next sibling
    Dim nt As XmlNodeType
    Do

        Await reader.SkipAsync()
        If (reader.ReadState <> ReadState.Interactive) Then
            Exit Do
        End If
        nt = reader.NodeType
        If ((nt = XmlNodeType.Element) And
           ((CObj(localName) = CObj(reader.LocalName))) And
           (CObj(namespaceURI) = CObj(reader.NamespaceURI))) Then
            Return True
        End If
    Loop While (nt <> XmlNodeType.EndElement And (Not reader.EOF))

    Return False

End Function

ReadToFollowing-methode

public static async Task<bool> ReadToFollowingAsync(this XmlReader reader, string localName, string namespaceURI)
{
    if (localName == null || localName.Length == 0)
    {
        throw new ArgumentException("localName is empty or null");
    }
    if (namespaceURI == null)
    {
        throw new ArgumentNullException("namespaceURI");
    }

    // atomize local name and namespace
    localName = reader.NameTable.Add(localName);
    namespaceURI = reader.NameTable.Add(namespaceURI);

    // find element with that name
    while (await reader.ReadAsync())
    {
        if (reader.NodeType == XmlNodeType.Element && ((object)localName == (object)reader.LocalName) && ((object)namespaceURI == (object)reader.NamespaceURI))
        {
            return true;
        }
    }
    return false;
}
<Extension()>
Public Async Function ReadToFollowingAsync(reader As XmlReader, localName As String, namespaceURI As String) As Task(Of Boolean)
    If (localName = Nothing Or localName.Length = 0) Then
        Throw New ArgumentException("localName is empty or null")
    End If

    If (namespaceURI = Nothing) Then
        Throw New ArgumentNullException("namespaceURI")
    End If

    ' atomize local name and namespace
    localName = reader.NameTable.Add(localName)
    namespaceURI = reader.NameTable.Add(namespaceURI)

    ' find element with that name
    While (Await reader.ReadAsync())
        If ((reader.NodeType = XmlNodeType.Element) And
           (CObj(localName) = CObj(reader.LocalName)) And
           (CObj(namespaceURI) = CObj(reader.NamespaceURI))) Then
            Return True
        End If
    End While

    Return False
End Function

Methode ReadToDescendant

public static async Task<bool> ReadToDescendantAsync(this XmlReader reader, string localName, string namespaceURI)
{
    if (localName == null || localName.Length == 0)
    {
        throw new ArgumentException("localName is empty or null");
    }
    if (namespaceURI == null)
    {
        throw new ArgumentNullException("namespaceURI");
    }
    // save the element or root depth
    int parentDepth = reader.Depth;
    if (reader.NodeType != XmlNodeType.Element)
    {
        // adjust the depth if we are on root node
        if (reader.ReadState == ReadState.Initial)
        {
            parentDepth--;
        }
        else
        {
            return false;
        }
    }
    else if (reader.IsEmptyElement)
    {
        return false;
    }

    // atomize local name and namespace
    localName = reader.NameTable.Add(localName);
    namespaceURI = reader.NameTable.Add(namespaceURI);

    // find the descendant
    while (await reader.ReadAsync() && reader.Depth > parentDepth)
    {
        if (reader.NodeType == XmlNodeType.Element && ((object)localName == (object)reader.LocalName) && ((object)namespaceURI == (object)reader.NamespaceURI))
        {
            return true;
        }
    }
    return false;
}
<Extension()>
Public Async Function ReadToDescendantAsync(reader As XmlReader, localName As String, namespaceURI As String) As Task(Of Boolean)
    If (localName = Nothing Or localName.Length = 0) Then
        Throw New ArgumentException("localName is empty or null")
    End If

    If (namespaceURI = Nothing) Then
        Throw New ArgumentNullException("namespaceURI")
    End If

    ' save the element or root depth
    Dim parentDepth As Integer = reader.Depth
    If (reader.NodeType <> XmlNodeType.Element) Then
        ' adjust the depth if we are on root node
        If (reader.ReadState = ReadState.Initial) Then
            parentDepth -= 1
        Else
            Return False
        End If
    ElseIf (reader.IsEmptyElement) Then
        Return False
    End If
    ' atomize local name and namespace
    localName = reader.NameTable.Add(localName)
    namespaceURI = reader.NameTable.Add(namespaceURI)

    ' find the descendant
    While (Await reader.ReadAsync() And reader.Depth > parentDepth)
        If (reader.NodeType = XmlNodeType.Element And
           (CObj(localName) = CObj(reader.LocalName)) And
           (CObj(namespaceURI) = CObj(reader.NamespaceURI))) Then
            Return True
        End If
    End While

    Return False
End Function

Beveiligingsoverwegingen

Houd rekening met het volgende bij het werken met de XmlReader klasse:

  • Uitzonderingen die door het XmlReader worden veroorzaakt, kunnen padinformatie vrijgeven die u mogelijk niet naar uw app wilt laten uitlekken. Uw app moet uitzonderingen onderscheppen en ze op de juiste manier verwerken.

  • Schakel DTD-verwerking niet in als u zich zorgen maakt over denial of service-problemen of als u te maken hebt met niet-vertrouwde bronnen. DTD-verwerking is standaard uitgeschakeld voor XmlReader objecten die door de Create methode zijn gemaakt.

    Als DTD-verwerking is ingeschakeld, kunt u de XmlSecureResolver gebruiken om de resources te beperken waartoe de XmlReader toegang heeft. U kunt uw app ook ontwerpen zodat de XML-verwerking geheugen en tijd beperkt is. U kunt bijvoorbeeld time-outlimieten configureren in uw ASP.NET-app.

  • XML-gegevens kunnen verwijzingen bevatten naar externe resources, zoals een schemabestand. Externe resources worden standaard omgezet met behulp van een XmlUrlResolver object zonder gebruikersreferenties. U kunt dit verder beveiligen door een van de volgende handelingen uit te voeren:

  • De ProcessInlineSchema en ProcessSchemaLocation validatievlagmen van een XmlReaderSettings object zijn niet standaard ingesteld. Dit helpt bij het beschermen van XmlReader tegen schema-gebaseerde aanvallen wanneer XML-gegevens van een niet-vertrouwde bron worden verwerkt. Wanneer deze vlaggen zijn ingesteld, wordt het XmlResolver-object van XmlReaderSettings gebruikt om schemalocaties, die zijn aangetroffen in het exemplaardocument in de XmlReader, op te lossen. Als de XmlResolver eigenschap is ingesteld op null, worden schemalocaties niet omgezet, zelfs niet als de ProcessInlineSchema en ProcessSchemaLocation validatievlagmen zijn ingesteld.

    Schema's die tijdens de validatie zijn toegevoegd, voegen nieuwe typen toe en kunnen het validatieresultaat van het document dat wordt gevalideerd, wijzigen. Als gevolg hiervan mogen externe schema's alleen worden omgezet vanuit vertrouwde bronnen.

    U wordt aangeraden de ProcessIdentityConstraints vlag uit te schakelen bij het valideren van niet-vertrouwde, grote XML-documenten in scenario's met hoge beschikbaarheid in een schema met identiteitsbeperkingen voor een groot deel van het document. Deze vlag is standaard ingeschakeld.

  • XML-gegevens kunnen een groot aantal kenmerken, naamruimtedeclaraties, geneste elementen, enzovoort bevatten, waarvoor een aanzienlijke hoeveelheid tijd nodig is om te verwerken. Als u de grootte wilt beperken van de invoer die naar de XmlReaderinvoer wordt verzonden, kunt u het volgende doen:

    • Beperk de grootte van het document door de MaxCharactersInDocument eigenschap in te stellen.

    • Beperk het aantal tekens dat het resultaat is van het uitbreiden van entiteiten door de eigenschap in te MaxCharactersFromEntities stellen.

    • Maak een aangepaste IStream implementatie voor de XmlReader.

  • De ReadValueChunk methode kan worden gebruikt om grote gegevensstromen te verwerken. Met deze methode wordt een klein aantal tekens tegelijk gelezen in plaats van één tekenreeks toe te wijzen voor de hele waarde.

  • Bij het lezen van een XML-document met een groot aantal unieke lokale namen, naamruimten of voorvoegsels kan er een probleem optreden. Als u een klasse gebruikt die is afgeleid van XmlReader, en u de LocalNameeigenschap , Prefixof NamespaceURI eigenschap aanroept voor elk item, wordt de geretourneerde tekenreeks toegevoegd aan een NameTable. De verzameling van de NameTable neemt nooit in grootte af, waardoor het een virtueel geheugenlek veroorzaakt van de strengegevens. Eén beperking hiervoor is het afleiden van de NameTable klasse en het afdwingen van een maximumgroottequotum. (Er is geen manier om het gebruik van een NameTable te voorkomen, of om NameTable te vervangen wanneer deze vol is). Een andere beperking is om het gebruik van de vermelde eigenschappen te voorkomen en in plaats daarvan de MoveToAttribute methode waar mogelijk te gebruiken met de IsStartElement methode. Deze methoden retourneren geen tekenreeksen en voorkomen zo het probleem van het overvullen van de NameTable verzameling.

  • XmlReaderSettings objecten kunnen gevoelige informatie bevatten, zoals gebruikersreferenties. Een niet-vertrouwd onderdeel kan het XmlReaderSettings object en de bijbehorende gebruikersreferenties gebruiken om objecten te maken XmlReader om gegevens te lezen. Wees voorzichtig bij het opslaan van objecten in de cache XmlReaderSettings of bij het doorgeven van het object van het ene onderdeel aan het XmlReaderSettings andere.

  • Accepteer geen ondersteunende onderdelen, zoals NameTable, XmlNamespaceManageren XmlResolver objecten, van een niet-vertrouwde bron.