Freigeben über


System.Xml.XmlReader-Klasse

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

XmlReader bietet einen schreibgeschützten Zugriff auf XML-Daten in einem Dokument oder Stream. Diese Klasse entspricht den Empfehlungen für W3C Extensible Markup Language (XML) 1.0 (vierte Edition) und den Namespaces in XML 1.0 (dritte Edition).

XmlReader mit Methoden können Sie XML-Daten durchlaufen und den Inhalt eines Knotens lesen. Die Eigenschaften der Klasse spiegeln den Wert des aktuellen Knotens wider, an dem der Leser positioniert ist. Der ReadState Eigenschaftswert gibt den aktuellen Status des XML-Readers an. Die Eigenschaft wird beispielsweise durch die ReadState.Initial Methode auf XmlReader.Read und durch die ReadState.Closed Methode auf XmlReader.Close gesetzt. XmlReader stellt außerdem Datenkonformitätsprüfungen und -validierungen für eine DTD oder ein Schema bereit.

XmlReader verwendet ein Pullmodell zum Abrufen von Daten. Dieses Modell:

  • Vereinfacht die Statusverwaltung durch eine natürliche Prozedur von oben nach unten
  • Unterstützt mehrere Eingabedatenströme und Layering.
  • Ermöglicht dem Client, dem Parser einen Puffer zu geben, in den die Zeichenfolge direkt geschrieben wird, und somit die Notwendigkeit einer zusätzlichen Zeichenfolgenkopie zu vermeiden.
  • Unterstützt selektive Verarbeitung. Der Client kann Elemente überspringen und diese verarbeiten, die für die Anwendung von Interesse sind. Sie können eigenschaften auch im Voraus festlegen, um zu verwalten, wie der XML-Datenstrom verarbeitet wird (z. B. Normalisierung).

Erstellen eines XML-Readers

Verwenden Sie die Create Methode, um eine XmlReader Instanz zu erstellen.

Obwohl .NET konkrete Implementierungen der XmlReader Klasse bereitstellt, z. B. das XmlTextReader, XmlNodeReaderund die XmlValidatingReader Klassen, empfehlen wir, die speziellen Klassen nur in diesen Szenarien zu verwenden:

  • Wenn Sie eine XML-DOM-Unterstruktur aus einem XmlNode Objekt lesen möchten, verwenden Sie die XmlNodeReader Klasse. (Diese Klasse unterstützt jedoch keine DTD- oder Schemaüberprüfung.)
  • Wenn Sie Entitäten auf Anforderung erweitern müssen, möchten Sie den Textinhalt nicht normalisieren, oder Sie möchten keine Standardattribute zurückgeben, verwenden Sie die XmlTextReader Klasse.

Um den Satz von Features anzugeben, die Sie für den XML-Reader aktivieren möchten, übergeben Sie ein System.Xml.XmlReaderSettings Objekt an die Create Methode. Sie können ein einzelnes System.Xml.XmlReaderSettings Objekt verwenden, um mehrere Leser mit derselben Funktionalität zu erstellen, oder das System.Xml.XmlReaderSettings Objekt ändern, um einen neuen Reader mit einem anderen Satz von Features zu erstellen. Sie können auch problemlos Features zu einem vorhandenen Reader hinzufügen.

Wenn Sie kein Objekt verwenden System.Xml.XmlReaderSettings , werden Standardeinstellungen verwendet. Details finden Sie auf der Create Referenzseite.

XmlReader löst XmlException bei XML-Analysefehlern aus. Nachdem eine Ausnahme ausgelöst wurde, ist der Status des Lesers nicht vorhersehbar. Der gemeldete Knotentyp kann sich beispielsweise vom tatsächlichen Knotentyp des aktuellen Knotens unterscheiden. Verwenden Sie die ReadState Eigenschaft, um zu überprüfen, ob sich der Reader im Fehlerzustand befindet.

Überprüfen von XML-Daten

Zum Definieren der Struktur eines XML-Dokuments und seiner Elementbeziehungen, Datentypen und Inhaltseinschränkungen verwenden Sie eine Dokumenttypdefinition (DTD) oder ein XSD-Schema (XML Schema Definition Language). Ein XML-Dokument gilt als wohlgeformt, wenn es alle syntaktischen Anforderungen erfüllt, die von der W3C XML 1.0-Empfehlung definiert sind. Es wird als gültig betrachtet, wenn es wohlgeformt ist und auch den Einschränkungen entspricht, die durch seine DTD oder sein Schema definiert sind. (Siehe W3C XML Schema Teil 1: Strukturen und die W3C XML Schema Teil 2: Datentypen Empfehlungen.) Daher sind zwar alle gültigen XML-Dokumente wohlgeformt, aber nicht alle wohlgeformten XML-Dokumente sind gültig.

Sie können die Daten anhand einer DTD, eines Inline-XSD-Schemas oder eines XSD-Schemas überprüfen, das in einem XmlSchemaSet Objekt (einem Cache) gespeichert ist. Diese Szenarien werden auf der Create Referenzseite beschrieben. XmlReader unterstützt nicht die XML-Data Reduced (XDR) Schema-Validierung.

Sie verwenden die folgenden Einstellungen für die XmlReaderSettings Klasse, um anzugeben, welche Art von Überprüfung, falls vorhanden, die XmlReader Instanz unterstützt.

Diesen XmlReaderSettings-Member verwenden Angabe von
DtdProcessing-Eigenschaft Gibt an, ob die DTD-Verarbeitung zugelassen werden soll. Der Standardwert ist, die DTD-Verarbeitung zu verbieten.
ValidationType-Eigenschaft Gibt an, ob der Leser Daten überprüfen soll und welche Art von Überprüfung ausgeführt werden soll (DTD oder Schema). Der Standardwert ist keine Datenüberprüfung.
ValidationEventHandler-Ereignis Ein Ereignishandler zum Empfangen von Informationen zu Überprüfungsereignissen. Wenn kein Ereignishandler angegeben wird, wird beim ersten Überprüfungsfehler ein XmlException Fehler ausgelöst.
ValidationFlags-Eigenschaft Gibt zusätzliche Validierungsoptionen über die XmlSchemaValidationFlags-Enumerationsmember an:

- AllowXmlAttributes-- Xml-Attribute (xml:*) in Instanzdokumenten zulassen, auch wenn sie nicht im Schema definiert sind. Die Attribute werden basierend auf ihrem Datentyp überprüft. Auf der XmlSchemaValidationFlags Referenzseite finden Sie die Einstellung, die in bestimmten Szenarien verwendet werden soll. (Standardmäßig deaktiviert.)
- ProcessIdentityConstraints--Prozessidentitätseinschränkungen (xs:ID, , xs:IDREFxs:key, xs:keyref, xs:unique), die während der Überprüfung aufgetreten sind. (Standardmäßig aktiviert.)
- ProcessSchemaLocation --Schemas verarbeiten, die durch das xsi:schemaLocation- oder xsi:noNamespaceSchemaLocation-Attribut angegeben werden (Standardmäßig aktiviert.)
- ProcessInlineSchema-- Verarbeiten von Inline-XML-Schemas während der Überprüfung. (Standardmäßig deaktiviert.)
- ReportValidationWarnings--Melden Sie Ereignisse, wenn eine Überprüfungswarnung auftritt. Eine Warnung wird in der Regel ausgegeben, wenn kein DTD- oder XML-Schema vorhanden ist, um ein bestimmtes Element oder Attribut zu überprüfen. Dies ValidationEventHandler wird für Benachrichtigungen verwendet. (Standardmäßig deaktiviert.)
Schemas Die für die Validierung zu verwendende XmlSchemaSet.
XmlResolver-Eigenschaft XmlResolver wird zum Auflösen von und Zugreifen auf externe Ressourcen verwendet. Dies kann externe Entitäten wie DTDs und Schemata sowie alle im XML-Schema enthaltenen xs:include oder xs:import-Elemente umfassen. Wenn Sie XmlResolver nicht angeben, verwendet XmlReader einen Standardwert ohne Benutzeranmeldeinformationen für XmlUrlResolver.

Datenkonformität

XML-Reader, die von der Create Methode erstellt werden, erfüllen standardmäßig die folgenden Complianceanforderungen:

  • Neue Zeilen und Attributwerte werden gemäß der W3C XML 1.0-Empfehlung normalisiert.

  • Alle Entitäten werden automatisch erweitert.

  • In der Dokumenttypdefinition deklarierte Standardattribute werden immer hinzugefügt, auch wenn der Leser nicht überprüft.

  • Die Deklaration des XML-Präfixes, das dem richtigen XML-Namespace-URI zugeordnet ist, ist zulässig.

  • Die Notationsnamen in einer einzelnen NotationType Attributdeklaration und NmTokens in einer einzelnen Enumeration Attributdeklaration sind unterschiedlich.

Verwenden Sie diese XmlReaderSettings Eigenschaften, um den Typ der Konformitätsprüfungen anzugeben, die Sie aktivieren möchten:

XmlReaderSettings Diese Eigenschaft verwenden Bis Standard
CheckCharacters-Eigenschaft Aktivieren oder Deaktivieren von Überprüfungen für Folgendes:

- Zeichen liegen innerhalb des Bereichs zulässiger XML-Zeichen, wie im Abschnitt "2.2 Zeichen " der W3C XML 1.0-Empfehlung definiert.
- Alle XML-Namen sind gültig, wie im Abschnitt "2.3 Common Syntactic Constructs" der W3C XML 1.0-Empfehlung definiert.

Wenn diese Eigenschaft auf true (Standardeinstellung) festgelegt ist, wird eine XmlException Ausnahme ausgelöst, wenn die XML-Datei ungültige Zeichen oder ungültige XML-Namen enthält (z. B. beginnt ein Elementname mit einer Zahl).
Die Zeichen- und Namensüberprüfung ist aktiviert.

Das Festlegen von CheckCharacters auf false deaktiviert die Zeichenüberprüfung für Zeichenentitätsreferenzen. Wenn der Leser Textdaten verarbeitet, überprüft er immer, ob XML-Namen gültig sind, unabhängig von dieser Einstellung. Anmerkung: Die XML 1.0-Empfehlung erfordert die Konformität auf Dokumentebene, wenn eine DTD vorhanden ist. Daher wird ein ConformanceLevel.Fragment ausgelöst, wenn der Reader für die Unterstützung von XmlException konfiguriert ist, aber die XML-Daten eine Dokumenttypdefinition (DTD) enthalten.
ConformanceLevel-Eigenschaft Wählen Sie die Konformitätsstufe aus, die erzwungen werden soll:

- Document. Entspricht den Regeln für ein wohlgeformtes XML 1.0-Dokument.
- Fragment. Entspricht den Regeln für ein wohlgeformtes Dokumentfragment, das als externe analysierte Entität verwendet werden kann.
- Auto. Entspricht der vom Leser beschlossenen Ebene.

Wenn die Daten nicht konform sind, wird eine XmlException Ausnahme ausgelöst.
Document

Der aktuelle Knoten ist der XML-Knoten, auf dem der XML-Reader derzeit positioniert ist. Alle XmlReader Methoden führen Vorgänge in Bezug auf diesen Knoten aus, und alle XmlReader Eigenschaften spiegeln den Wert des aktuellen Knotens wider.

Mit den folgenden Methoden können Sie einfach durch Knoten navigieren und Daten analysieren.

Verwenden Sie diese XmlReaderSettings Methode. Bis
Read Lesen Sie den ersten Knoten, und durchlaufen Sie den Stream Knoten für Knoten. Solche Aufrufe werden in der Regel innerhalb einer while Schleife ausgeführt.

Verwenden Sie die NodeType Eigenschaft, um den Typ (z. B. Attribut, Kommentar, Element usw.) des aktuellen Knotens abzurufen.
Skip Überspringen Sie die untergeordneten Elemente des aktuellen Knotens, und fahren Sie mit dem nächsten Knoten fort.
MoveToContent und MoveToContentAsync Überspringen Sie Nicht-Inhaltsknoten, und wechseln Sie zum nächsten Inhaltsknoten oder zum Ende der Datei.

Nicht-Inhaltsknoten umfassen ProcessingInstruction, , DocumentType, Comment, Whitespaceund SignificantWhitespace.

Zu Inhaltsknoten zählen Textknoten ohne Leerzeichen wie CDATA, EntityReference und EndEntity.
ReadSubtree Lesen Sie ein Element und alle untergeordneten Elemente, und geben Sie eine neue XmlReader-Instanz zurück, die auf ReadState.Initial festgelegt ist.

Diese Methode ist nützlich, um Grenzen um XML-Elemente zu erstellen; Wenn Sie z. B. Daten zur Verarbeitung an eine andere Komponente übergeben möchten und sie einschränken möchten, auf wie viele Daten die Komponente zugreifen kann.

Auf der XmlReader.Read-Referenzseite finden Sie ein Beispiel für die knotenweise Navigation durch einen Textstream und zum Anzeigen des Typs der einzelnen Knoten.

In den folgenden Abschnitten wird beschrieben, wie Sie bestimmte Datentypen lesen können, z. B. Elemente, Attribute und typierte Daten.

Lesen von XML-Elementen

In der folgenden Tabelle sind die Methoden und Eigenschaften aufgeführt, die von der Klasse für die XmlReader Verarbeitung von Elementen bereitgestellt werden. Nachdem XmlReader auf einem Element positioniert ist, spiegeln die Knoteneigenschaften, wie Name, die Elementwerte wider. Zusätzlich zu den unten beschriebenen Membern können alle allgemeinen Methoden und Eigenschaften der XmlReader Klasse auch zum Verarbeiten von Elementen verwendet werden. Sie können z. B. die ReadInnerXml Methode verwenden, um den Inhalt eines Elements zu lesen.

Hinweis

Siehe Abschnitt 3.1 der W3C XML 1.0-Empfehlung für Definitionen von Starttags, Endtags und leeren Elementtags.

Diesen XmlReader-Member verwenden Bis
IsStartElement-Methode Überprüft, ob der aktuelle Knoten ein Anfangstag oder ein leeres Elementtag ist
ReadStartElement-Methode Überprüft, ob es sich bei dem aktuellen Knoten um ein Element handelt, und fährt mit dem nächsten Knoten fort (ruft IsStartElement gefolgt von Read auf)
ReadEndElement-Methode Überprüft, ob der aktuelle Knoten ein Endtag ist, und rückt den Reader zum nächsten Knoten vor
ReadElementString-Methode Liest ein Nur-Text-Element
ReadToDescendant-Methode Rückt den XML-Reader zum nächsten untergeordneten Element mit dem angegebenen Namen vor
ReadToNextSibling-Methode Wechseln Sie den XML-Reader zum nächsten gleichgeordneten Element mit dem angegebenen Namen.
IsEmptyElement-Eigenschaft Überprüft, ob das aktuelle Element ein Endelementtag aufweist Beispiel:

- <item num="123"/> (IsEmptyElement ist true.)
- <item num="123"> </item> (IsEmptyElement ist false, obwohl der Inhalt des Elements leer ist.)

Ein Beispiel zum Lesen des Textinhalts von Elementen finden Sie in der ReadString Methode. Im folgenden Beispiel werden Elemente mithilfe einer while Schleife verarbeitet.

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

Lesen von XML-Attributen

XML-Attribute werden am häufigsten für Elemente gefunden, sind aber auch für XML-Deklarations- und Dokumenttypknoten zulässig.

Wenn sie auf einem Elementknoten positioniert ist, können Sie mit der MoveToAttribute Methode die Attributliste des Elements durchlaufen. Beachten Sie, dass nach dem MoveToAttribute Aufruf Knoteneigenschaften wie Name, NamespaceURIund Prefix die Eigenschaften dieses Attributs widerspiegeln, nicht die Eigenschaften des Elements, zu dem das Attribut gehört.

Die XmlReader Klasse stellt diese Methoden und Eigenschaften zum Lesen und Verarbeiten von Attributen für Elemente bereit.

Diesen XmlReader-Member verwenden Bis
HasAttributes-Eigenschaft Überprüfen Sie, ob der aktuelle Knoten Attribute aufweist.
AttributeCount-Eigenschaft Ruft die Anzahl der Attribute für das aktuelle Element ab.
MoveToFirstAttribute-Methode Wechseln zum ersten Attribut in einem Element.
MoveToNextAttribute-Methode Wechseln zum nächsten Attribut in einem Element.
MoveToAttribute-Methode Wechseln zu einem angegebenen Attribut.
GetAttribute Methode oder Item[] Eigenschaft Rufen Sie den Wert eines angegebenen Attributs ab.
IsDefault-Eigenschaft Überprüfen Sie, ob es sich bei dem aktuellen Knoten um ein Attribut handelt, das aus dem standardwert generiert wurde, der in der DTD oder im Schema definiert ist.
MoveToElement-Methode Wechseln zum Element, das das aktuelle Attribut besitzt. Verwenden Sie diese Methode, um nach dem Navigieren durch die Attribute zu einem Element zurückzukehren.
ReadAttributeValue-Methode Zerlegen Sie den Attributwert in einen Text, mehrere EntityReference oder EndEntity Knoten.

Alle allgemeinen XmlReader Methoden und Eigenschaften können auch zum Verarbeiten von Attributen verwendet werden. Nachdem das XmlReader auf einem Attribut positioniert ist, spiegeln die Name- und Value-Eigenschaften die Werte des Attributs wider. Sie können auch eine der Inhaltsmethoden Read verwenden, um den Wert des Attributs abzurufen.

In diesem Beispiel wird die AttributeCount Eigenschaft verwendet, um durch alle Attribute eines Elements zu navigieren.

// 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 diesem Beispiel wird die MoveToNextAttribute Methode in einer while Schleife verwendet, um durch die Attribute zu navigieren.

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

Lesen von Attributen auf XML-Deklarationsknoten

Wenn der XML-Reader auf einem XML-Deklarationsknoten positioniert wird, gibt die Value Eigenschaft die Versions-, eigenständigen und Codierungsinformationen als einzelne Zeichenfolge zurück. XmlReader Von der Create Methode, der XmlTextReader Klasse und der XmlValidatingReader Klasse erstellte Objekte machen die Versions-, eigenständigen und Codierungselemente als Attribute verfügbar.

Lesen von Attributen auf Dokumenttypknoten

Wenn der XML-Reader auf einem Dokumenttypknoten positioniert ist, kann die GetAttribute Methode und Item[] Eigenschaft verwendet werden, um die Werte für die Literale SYSTEM und PUBLIC zurückzugeben. Das Aufrufen reader.GetAttribute("PUBLIC") gibt z. B. den PUBLIC-Wert zurück.

Lesen von Attributen auf Knoten von Verarbeitungsanweisungen

Wenn die XmlReader Position auf einem Verarbeitungsanweisungsknoten erfolgt, gibt die Value Eigenschaft den gesamten Textinhalt zurück. Elemente im Verarbeitungsanweisungsknoten werden nicht als Attribute behandelt. Sie können nicht mit der GetAttribute- oder der MoveToAttribute-Methode gelesen werden.

XML-Inhalt lesen

Die XmlReader-Klasse enthält die folgenden Member, die Inhalte aus einer XML-Datei lesen und den Inhalt als Zeichenfolgenwerte zurückgeben. (Informationen zum Zurückgeben von CLR-Typen finden Sie unter Konvertieren in CLR-Typen.)

Diesen XmlReader-Member verwenden Bis
Value-Eigenschaft Rufen Sie den Textinhalt des aktuellen Knotens ab. Der zurückgegebene Wert hängt vom Knotentyp ab; Weitere Informationen finden Sie auf der Value Referenzseite.
ReadString-Methode Dient zum Abrufen des Inhalts eines Elements oder Eines Textknotens als Zeichenfolge. Diese Methode beendet die Verarbeitung von Anweisungen und Kommentaren.

Ausführliche Informationen dazu, wie diese Methode bestimmte Knotentypen behandelt, finden Sie auf der ReadString Referenzseite.
Die Methoden ReadInnerXml und ReadInnerXmlAsync Rufen Sie den gesamten Inhalt des aktuellen Knotens ab, einschließlich des Markups, mit Ausnahme von Start- und Endtags. Beispiel:

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

ReadInnerXml gibt Folgendes zurück:

this<child id="123"/>
Die Methoden ReadOuterXml und ReadOuterXmlAsync Ruft alle Inhalte des aktuellen Knotens und der untergeordneten Elemente ab, einschließlich Markup und Start-/Endtags. Beispiel:

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

ReadOuterXml gibt Folgendes zurück:

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

In CLR-Typen konvertieren

Sie können die Member der Klasse (in der XmlReader folgenden Tabelle aufgeführt) verwenden, um XML-Daten zu lesen und Werte als CLR-Typen (Common Language Runtime) anstelle von Zeichenfolgen zurückzugeben. Mit diesen Membern können Sie Werte in der Darstellung abrufen, die für Ihre Codierungsaufgabe am besten geeignet ist, ohne Zeichenfolgenwerte manuell analysieren oder konvertieren zu müssen.

  • Die ReadElementContentAs-Methoden können nur für Elementknotentypen aufgerufen werden. Diese Methoden können nur für Elemente verwendet werden, die untergeordnete Elemente oder gemischten Inhalt enthalten. Bei einem Aufruf liest das XmlReader-Objekt das Anfangstag und den Elementinhalt und wird hinter das Endelementtag verschoben. Verarbeitungsanweisungen und Kommentare werden ignoriert, und Entitäten werden erweitert.

  • Die ReadContentAs-Methoden lesen den Textinhalt an der aktuellen Leseposition, und wenn den XML-Daten keine Schema- oder Datentypinformationen zugeordnet sind, konvertieren Sie den Textinhalt in den angeforderten Rückgabetyp. Text, Leerraum, signifikanter Leerraum und CDATA-Abschnitte sind verkettet. Kommentare und Verarbeitungsanweisungen werden übersprungen, und Entitätsverweise werden automatisch aufgelöst.

Die XmlReader Klasse verwendet die Regeln, die in der Empfehlung W3C XML Schema Part 2: Datatypes definiert sind.

Verwenden Sie diese XmlReader Methode. CLR-Rückgabetyp
ReadContentAsBoolean und ReadElementContentAsBoolean Boolean
ReadContentAsDateTime und ReadElementContentAsDateTime DateTime
ReadContentAsDouble und ReadElementContentAsDouble Double
ReadContentAsLong und ReadElementContentAsLong Int64
ReadContentAsInt und ReadElementContentAsInt Int32
ReadContentAsString und ReadElementContentAsString String
ReadContentAs und ReadElementContentAs Der Typ, den Sie mit dem returnType Parameter angeben
ReadContentAsObject und ReadElementContentAsObject Der am besten geeignete Typ, wie durch die XmlReader.ValueType Eigenschaft angegeben. Informationen zur Zuordnung finden Sie unter "Typunterstützung" in den System.Xml-Klassen .

Wenn ein Element aufgrund seines Formats nicht einfach in einen CLR-Typ konvertiert werden kann, können Sie eine Schemazuordnung verwenden, um eine erfolgreiche Konvertierung sicherzustellen. Im folgenden Beispiel wird eine XSD-Datei verwendet, um das hire-date Element in den xs:date Typ zu konvertieren, und anschließend wird die ReadElementContentAsDateTime Methode verwendet, um das Element als DateTime Objekt zurückzugeben.

Input (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

Ausgabe:

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

Asynchrone Programmierung

XmlReader Die meisten Methoden weisen asynchrone Entsprechungen auf, die am Ende der Methodennamen "Async" haben. Zum Beispiel ist die asynchrone Entsprechung von ReadContentAsObjectReadContentAsObjectAsync.

Die folgenden Methoden können mit asynchronen Methodenaufrufen verwendet werden:

In den folgenden Abschnitten wird die asynchrone Verwendung für Methoden beschrieben, die nicht über asynchrone Entsprechungen verfügen.

ReadStartElement-Methode

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

ReadEndElement-Methode

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

ReadToNextSibling Methode

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

ReadToDescendant-Methode

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

Sicherheitsüberlegungen

Berücksichtigen Sie beim Arbeiten mit der XmlReader Klasse Folgendes:

  • Ausnahmen, die von XmlReader ausgelöst werden, können Pfadinformationen offenlegen, die Sie möglicherweise nicht an Ihre App weiterleiten möchten. Ihre App muss Ausnahmen erfassen und entsprechend verarbeiten.

  • Aktivieren Sie die DTD-Verarbeitung nicht, wenn Sie sich Gedanken über Denial-of-Service-Angriffe machen oder wenn Sie mit nicht vertrauenswürdigen Quellen arbeiten. DIE DTD-Verarbeitung ist standardmäßig für XmlReader Objekte deaktiviert, die von der Create Methode erstellt wurden.

    Wenn die DTD-Verarbeitung aktiviert ist, können Sie die XmlSecureResolver Ressourcen einschränken, auf die der XmlReader Zugriff möglich ist. Sie können Ihre App auch so entwerfen, dass die XML-Verarbeitung arbeitsspeicher- und zeitschränkt ist. Sie können beispielsweise Zeitlimits in Ihrer ASP.NET-App konfigurieren.

  • XML-Daten können Verweise auf externe Ressourcen wie eine Schemadatei enthalten. Standardmäßig werden externe Ressourcen mithilfe eines XmlUrlResolver Objekts ohne Benutzeranmeldeinformationen aufgelöst. Sie können dies weiter sichern, indem Sie eine der folgenden Aktionen ausführen:

  • Die ProcessInlineSchema und ProcessSchemaLocation Validierungskennzeichnungen eines XmlReaderSettings Objekts sind nicht standardmäßig gesetzt. Dies trägt zum Schutz XmlReader vor schemabasierten Angriffen bei der Verarbeitung von XML-Daten aus einer nicht vertrauenswürdigen Quelle bei. Wenn diese Flags festgelegt sind, wird der XmlResolver des XmlReaderSettings-Objekts verwendet, um die im Instanzdokument des XmlReader erkannten Schemaspeicherorte aufzulösen. Wenn die XmlResolver Eigenschaft auf null festgelegt ist, werden Schemaspeicherplätze nicht aufgelöst, auch wenn die Validierungsflags ProcessInlineSchema und ProcessSchemaLocation gesetzt sind.

    Schemas, die während der Überprüfung hinzugefügt wurden, fügen neue Typen hinzu und können das Überprüfungsergebnis des überprüften Dokuments ändern. Daher sollten externe Schemas nur aus vertrauenswürdigen Quellen aufgelöst werden.

    Es wird empfohlen, das ProcessIdentityConstraints Kennzeichen beim Überprüfen nicht vertrauenswürdiger, großer XML-Dokumente in Hochverfügbarkeitsszenarien für ein Schema zu deaktivieren, das Über Identitätseinschränkungen für einen großen Teil des Dokuments verfügt. Dieses Kennzeichen ist standardmäßig aktiviert.

  • XML-Daten können eine große Anzahl von Attributen, Namespacedeklarationen, geschachtelten Elementen usw. enthalten, die eine erhebliche Zeit für die Verarbeitung erfordern. Um die Größe der an die XmlReaderEingabe gesendeten Eingabe einzuschränken, können Sie:

    • Beschränken Sie die Größe des Dokuments, indem Sie die MaxCharactersInDocument Eigenschaft festlegen.

    • Beschränken Sie die Anzahl von Zeichen, die sich aus der Erweiterung von Entitäten ergeben, indem Sie die MaxCharactersFromEntities Eigenschaft festlegen.

    • Erstellen Sie eine benutzerdefinierte IStream Implementierung für die XmlReader.

  • Die ReadValueChunk Methode kann verwendet werden, um große Datenströme zu verarbeiten. Diese Methode liest eine kleine Anzahl von Zeichen gleichzeitig, anstatt eine einzelne Zeichenfolge für den gesamten Wert zu zuordnen.

  • Beim Lesen eines XML-Dokuments mit einer großen Anzahl eindeutiger lokaler Namen, Namespaces oder Präfixe kann ein Problem auftreten. Wenn Sie eine Klasse verwenden, die von XmlReader abgeleitet ist, und Sie die Eigenschaft LocalName, Prefix oder NamespaceURI für jedes Element aufrufen, wird die zurückgegebene Zeichenfolge zu einem NameTable hinzugefügt. Die Größe der in der NameTable gespeicherten Collection nimmt nie ab, sodass ein virtueller Arbeitsspeicherverlust der Zeichenfolgenhandles eintritt. Eine Lösung dafür besteht darin, von der NameTable Klasse abzuleiten und eine maximale Größenbeschränkung zu erzwingen. (Es gibt keine Möglichkeit, die Verwendung eines NameTable zu verhindern oder das NameTable zu wechseln, wenn es voll ist). Eine weitere Entschärfung besteht darin, die Verwendung der erwähnten Eigenschaften zu vermeiden und stattdessen die MoveToAttribute Methode mit der IsStartElement Methode nach Möglichkeit zu verwenden. Diese Methoden geben keine Zeichenfolgen zurück und vermeiden so das Problem, die NameTable Auflistung zu überfüllen.

  • XmlReaderSettings Objekte können vertrauliche Informationen wie Benutzeranmeldeinformationen enthalten. Eine nicht vertrauenswürdige Komponente kann das XmlReaderSettings Objekt und seine Benutzeranmeldeinformationen verwenden, um Objekte zum Lesen von Daten zu erstellen XmlReader . Achten Sie beim Zwischenspeichern XmlReaderSettings von Objekten oder beim Übergeben des XmlReaderSettings Objekts von einer Komponente an eine andere.

  • Akzeptieren Sie keine unterstützenden Komponenten, wie z. B. NameTable, XmlNamespaceManager und XmlResolver-Objekte, aus einer nicht vertrauenswürdigen Quelle.