Share via


Kelas System.Xml.XmlReader

Artikel ini menyediakan keterangan tambahan untuk dokumentasi referensi untuk API ini.

XmlReader menyediakan akses hanya-terusan dan baca-saja ke data XML dalam dokumen atau aliran. Kelas ini sesuai dengan rekomendasi W3C Extensible Markup Language (XML) 1.0 (edisi keempat) dan Namespace dalam XML 1.0 (edisi ketiga).

XmlReader metode memungkinkan Anda menelusuri data XML dan membaca konten simpul. Properti kelas mencerminkan nilai simpul saat ini, yang merupakan tempat pembaca diposisikan. Nilai ReadState properti menunjukkan status pembaca XML saat ini. Misalnya, properti diatur ke ReadState.Initial dengan XmlReader.Read metode dan ReadState.Closed dengan XmlReader.Close metode . XmlReader juga menyediakan pemeriksaan dan validasi kesamaan data terhadap DTD atau skema.

XmlReader menggunakan model penarikan untuk mengambil data. Model ini:

  • Menyederhanakan manajemen status dengan penyempurnaan prosedural alami dan top-down.
  • Mendukung beberapa aliran input dan lapisan.
  • Memungkinkan klien untuk memberi pengurai buffer tempat string ditulis secara langsung, dan dengan demikian menghindari kebutuhan salinan string tambahan.
  • Mendukung pemrosesan selektif. Klien dapat melewati item dan memproses item yang menarik bagi aplikasi. Anda juga dapat mengatur properti terlebih dahulu untuk mengelola bagaimana aliran XML diproses (misalnya, normalisasi).

Membuat pembaca XML

Create Gunakan metode untuk membuat XmlReader instans.

Meskipun .NET menyediakan implementasi konkret kelas XmlReader , seperti XmlTextReader, , XmlNodeReaderdan XmlValidatingReader kelas, kami sarankan Anda menggunakan kelas khusus hanya dalam skenario ini:

  • Saat Anda ingin membaca subtree XML DOM dari XmlNode objek, gunakan XmlNodeReader kelas . (Namun, kelas ini tidak mendukung validasi DTD atau skema.)
  • Jika Anda harus memperluas entitas berdasarkan permintaan, Anda tidak ingin konten teks Anda dinormalisasi, atau Anda tidak ingin atribut default dikembalikan, gunakan XmlTextReader kelas .

Untuk menentukan kumpulan fitur yang ingin Anda aktifkan pada pembaca XML, teruskan System.Xml.XmlReaderSettings objek ke Create metode . Anda dapat menggunakan satu System.Xml.XmlReaderSettings objek untuk membuat beberapa pembaca dengan fungsionalitas yang sama, atau memodifikasi System.Xml.XmlReaderSettings objek untuk membuat pembaca baru dengan serangkaian fitur yang berbeda. Anda juga dapat dengan mudah menambahkan fitur ke pembaca yang ada.

Jika Anda tidak menggunakan System.Xml.XmlReaderSettings objek, pengaturan default akan digunakan. Lihat halaman Create referensi untuk detailnya.

XmlReader melempar kesalahan XmlException penguraian XML. Setelah pengecualian dilemparkan, status pembaca tidak dapat diprediksi. Misalnya, jenis node yang dilaporkan mungkin berbeda dari jenis node aktual dari simpul saat ini. ReadState Gunakan properti untuk memeriksa apakah pembaca dalam status kesalahan.

Memvalidasi data XML

Untuk menentukan struktur dokumen XML dan hubungan elemen, jenis data, dan batasan kontennya, Anda menggunakan skema definisi tipe dokumen (DTD) atau bahasa definisi Skema XML (XSD). Dokumen XML dianggap terbentuk dengan baik jika memenuhi semua persyaratan sintetis yang ditentukan oleh Rekomendasi XML 1.0 W3C. Ini dianggap valid jika terbentuk dengan baik dan juga sesuai dengan batasan yang ditentukan oleh DTD atau skemanya. (Lihat Skema XML W3C Bagian 1: Struktur dan Skema XML W3C Bagian 2: Rekomendasi jenis data.) Oleh karena itu, meskipun semua dokumen XML yang valid terbentuk dengan baik, tidak semua dokumen XML yang dibentuk dengan baik valid.

Anda dapat memvalidasi data terhadap DTD, Skema XSD sebaris, atau Skema XSD yang XmlSchemaSet disimpan dalam objek (cache); skenario ini dijelaskan di Create halaman referensi. XmlReader tidak mendukung validasi skema XML-Data Reduced (XDR).

Anda menggunakan pengaturan berikut pada XmlReaderSettings kelas untuk menentukan jenis validasi apa, jika ada, XmlReader yang didukung instans.

Gunakan anggota ini XmlReaderSettings Untuk menentukan
Properti DtdProcessing Apakah akan mengizinkan pemrosesan DTD. Defaultnya adalah melarang pemrosesan DTD.
Properti ValidationType Apakah pembaca harus memvalidasi data, dan jenis validasi apa yang harus dilakukan (DTD atau skema). Defaultnya adalah tidak ada validasi data.
Peristiwa ValidationEventHandler Penanganan aktivitas untuk menerima informasi tentang peristiwa validasi. Jika penanganan aktivitas tidak disediakan, akan XmlException dilemparkan pada kesalahan validasi pertama.
Properti ValidationFlags Opsi validasi tambahan melalui XmlSchemaValidationFlags anggota enumerasi:

- AllowXmlAttributes-- Izinkan atribut XML (xml:*) dalam dokumen instans bahkan ketika tidak ditentukan dalam skema. Atribut divalidasi berdasarkan jenis datanya. XmlSchemaValidationFlags Lihat halaman referensi untuk pengaturan yang akan digunakan dalam skenario tertentu. (Dinonaktifkan secara default.)
- ProcessIdentityConstraints--Memproses batasan identitas (xs:ID, , xs:IDREF, xs:keyxs:keyref, xs:unique) yang ditemui selama validasi. (Diaktifkan secara default.)
- ProcessSchemaLocation --Proses skema yang ditentukan oleh xsi:schemaLocation atribut atau xsi:noNamespaceSchemaLocation . (Diaktifkan secara default.)
- ProcessInlineSchema-- Proses Skema XML sebaris selama validasi. (Dinonaktifkan secara default.)
- ReportValidationWarnings--Laporkan peristiwa jika terjadi peringatan validasi. Peringatan biasanya dikeluarkan ketika tidak ada Skema DTD atau XML untuk memvalidasi elemen atau atribut tertentu. ValidationEventHandler digunakan untuk pemberitahuan. (Dinonaktifkan secara default.)
Schemas yang XmlSchemaSet digunakan untuk validasi.
Properti XmlResolver XmlResolver untuk menyelesaikan dan mengakses sumber daya eksternal. Ini dapat mencakup entitas eksternal seperti DTD dan skema, dan elemen atau xs:import apa pun xs:include yang terkandung dalam Skema XML. Jika Anda tidak menentukan XmlResolver, XmlReader menggunakan default XmlUrlResolver tanpa kredensial pengguna.

Kesuaian data

Pembaca XML yang dibuat oleh Create metode memenuhi persyaratan kepatuhan berikut secara default:

  • Baris baru dan nilai atribut dinormalisasi sesuai dengan Rekomendasi XML 1.0 W3C.

  • Semua entitas secara otomatis diperluas.

  • Atribut default yang dideklarasikan dalam definisi jenis dokumen selalu ditambahkan bahkan ketika pembaca tidak memvalidasi.

  • Deklarasi awalan XML yang dipetakan ke URI namespace XML yang benar diizinkan.

  • Nama notasi dalam deklarasi atribut tunggal NotationType dan NmTokens dalam satu Enumeration deklarasi atribut berbeda.

Gunakan properti ini XmlReaderSettings untuk menentukan jenis pemeriksaan kesuaian yang ingin Anda aktifkan:

Gunakan properti ini XmlReaderSettings Untuk Default
Properti CheckCharacters Aktifkan atau nonaktifkan pemeriksaan untuk hal berikut:

- Karakter berada dalam rentang karakter XML legal, seperti yang didefinisikan oleh bagian 2.2 Karakter dari Rekomendasi XML W3C 1.0.
- Semua nama XML valid, seperti yang didefinisikan oleh bagian Konstruksi Syntactic Umum 2.3 dari Rekomendasi XML W3C 1.0.

Ketika properti ini diatur ke true (default), XmlException pengecualian dilemparkan jika file XML berisi karakter ilegal atau nama XML yang tidak valid (misalnya, nama elemen dimulai dengan angka).
Pemeriksaan karakter dan nama diaktifkan.

Pengaturan CheckCharacters untuk false menonaktifkan pemeriksaan karakter untuk referensi entitas karakter. Jika pembaca memproses data teks, selalu memeriksa bahwa nama XML valid, terlepas dari pengaturan ini. Catatan: Rekomendasi XML 1.0 memerlukan kesamaan tingkat dokumen saat DTD ada. Oleh karena itu, jika pembaca dikonfigurasi untuk mendukung ConformanceLevel.Fragment, tetapi data XML berisi definisi jenis dokumen (DTD), akan XmlException dilemparkan.
Properti ConformanceLevel Pilih tingkat kesuaian yang akan diberlakukan:

- Document. Sesuai dengan aturan untuk dokumen XML 1.0 yang terbentuk dengan baik.
- Fragment. Sesuai dengan aturan untuk fragmen dokumen yang terbentuk dengan baik yang dapat digunakan sebagai entitas yang diurai eksternal.
- Auto. Sesuai dengan tingkat yang diputuskan oleh pembaca.

Jika data tidak sesuai, XmlException pengecualian akan dilemparkan.
Document

Simpul saat ini adalah simpul XML tempat pembaca XML saat ini diposisikan. Semua XmlReader metode melakukan operasi sehubungan dengan simpul ini, dan semua XmlReader properti mencerminkan nilai simpul saat ini.

Metode berikut memudahkan untuk menavigasi melalui simpul dan mengurai data.

Gunakan metode ini XmlReaderSettings Untuk
Read Baca simpul pertama, dan lanjutkan melalui streaming satu simpul sekaligus. Panggilan tersebut biasanya dilakukan di dalam perulangan while .

NodeType Gunakan properti untuk mendapatkan jenis (misalnya, atribut, komentar, elemen, dan sebagainya) dari simpul saat ini.
Skip Lewati turunan simpul saat ini dan pindah ke simpul berikutnya.
MoveToContent dan MoveToContentAsync Lewati simpul non-konten dan pindah ke simpul konten berikutnya atau ke akhir file.

Node non-konten meliputi ProcessingInstruction, , CommentDocumentType, Whitespace, dan SignificantWhitespace.

Node konten mencakup teks spasi non-putih, CDATA, EntityReference , dan EndEntity.
ReadSubtree Baca elemen dan semua turunannya, dan kembalikan instans baru XmlReader yang diatur ke ReadState.Initial.

Metode ini berguna untuk membuat batas di sekitar elemen XML; misalnya, jika Anda ingin meneruskan data ke komponen lain untuk diproses dan Anda ingin membatasi berapa banyak data yang dapat diakses komponen.

XmlReader.Read Lihat halaman referensi untuk contoh menavigasi melalui aliran teks satu simpul sekaligus dan menampilkan jenis setiap simpul.

Bagian berikut ini menjelaskan cara membaca jenis data tertentu, seperti elemen, atribut, dan data yang ditik.

Membaca elemen XML

Tabel berikut mencantumkan metode dan properti yang XmlReader disediakan kelas untuk elemen pemrosesan. XmlReader Setelah diposisikan pada elemen, properti simpul, seperti Name, mencerminkan nilai elemen. Selain anggota yang dijelaskan di bawah ini, salah satu metode umum dan properti XmlReader kelas juga dapat digunakan untuk memproses elemen. Misalnya, Anda dapat menggunakan ReadInnerXml metode untuk membaca konten elemen.

Catatan

Lihat bagian 3.1 dari Rekomendasi W3C XML 1.0 untuk definisi tag mulai, tag akhir, dan tag elemen kosong.

Gunakan anggota ini XmlReader Untuk
metode IsStartElement Periksa apakah simpul saat ini adalah tag mulai atau tag elemen kosong.
metode ReadStartElement Periksa apakah simpul saat ini adalah elemen dan lanjutkan pembaca ke simpul berikutnya (panggilan IsStartElement diikuti oleh Read).
metode ReadEndElement Periksa apakah simpul saat ini adalah tag akhir dan lanjutkan pembaca ke simpul berikutnya.
metode ReadElementString Membaca elemen teks saja.
metode ReadToDescendant Lanjutkan pembaca XML ke elemen turunan (turunan) berikutnya yang memiliki nama yang ditentukan.
metode ReadToNextSibling Lanjutkan pembaca XML ke elemen saudara kandung berikutnya yang memiliki nama yang ditentukan.
Properti IsEmptyElement Periksa apakah elemen saat ini memiliki tag elemen akhir. Misalnya:

- <item num="123"/> (IsEmptyElement adalah true.)
- <item num="123"> </item> (IsEmptyElement adalah false, meskipun konten elemen kosong.)

Untuk contoh membaca konten teks elemen, lihat ReadString metode . Contoh berikut memproses elemen dengan menggunakan perulangan while .

while (reader.Read()) {
  if (reader.IsStartElement()) {
    if (reader.IsEmptyElement)
                {
                    Console.WriteLine("<{0}/>", 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

Membaca atribut XML

Atribut XML paling umum ditemukan pada elemen, tetapi juga diizinkan pada deklarasi XML dan node jenis dokumen.

Ketika diposisikan pada node elemen, MoveToAttribute metode ini memungkinkan Anda melalui daftar atribut elemen. Perhatikan bahwa setelah MoveToAttribute dipanggil, properti node seperti Name, NamespaceURI, dan Prefix mencerminkan properti atribut tersebut, bukan properti elemen tempat atribut berada.

Kelas XmlReader ini menyediakan metode dan properti ini untuk membaca dan memproses atribut pada elemen.

Gunakan anggota ini XmlReader Untuk
Properti HasAttributes Periksa apakah simpul saat ini memiliki atribut apa pun.
Properti AttributeCount Dapatkan jumlah atribut pada elemen saat ini.
metode MoveToFirstAttribute Pindah ke atribut pertama dalam elemen.
metode MoveToNextAttribute Pindah ke atribut berikutnya dalam elemen.
metode MoveToAttribute Pindah ke atribut tertentu.
GetAttribute metode atau Item[] properti Dapatkan nilai atribut tertentu.
Properti IsDefault Periksa apakah simpul saat ini adalah atribut yang dihasilkan dari nilai default yang ditentukan dalam DTD atau skema.
metode MoveToElement Pindah ke elemen yang memiliki atribut saat ini. Gunakan metode ini untuk kembali ke elemen setelah menavigasi melalui atributnya.
metode ReadAttributeValue Uraikan nilai atribut ke dalam satu atau beberapa Textsimpul , , EntityReferenceatau EndEntity .

Salah satu metode dan properti umum XmlReader juga dapat digunakan untuk memproses atribut. Misalnya, setelah XmlReader diposisikan pada atribut, Name properti dan Value mencerminkan nilai atribut. Anda juga dapat menggunakan salah satu metode konten Read untuk mendapatkan nilai atribut.

Contoh ini menggunakan AttributeCount properti untuk menavigasi semua atribut pada elemen.

// Display all attributes.
if (reader.HasAttributes) {
  Console.WriteLine("Attributes of <" + reader.Name + ">");
  for (int i = 0; i < reader.AttributeCount; i++) {
    Console.WriteLine("  {0}", 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

Contoh ini menggunakan MoveToNextAttribute metode dalam perulangan while untuk menavigasi melalui atribut.

if (reader.HasAttributes) {
  Console.WriteLine("Attributes of <" + reader.Name + ">");
  while (reader.MoveToNextAttribute()) {
    Console.WriteLine(" {0}={1}", 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

Membaca atribut pada simpul deklarasi XML

Saat pembaca XML diposisikan pada simpul deklarasi XML, Value properti mengembalikan informasi versi, mandiri, dan pengodean sebagai string tunggal. XmlReader objek yang dibuat oleh Create metode, XmlTextReader kelas, dan XmlValidatingReader kelas mengekspos versi, item mandiri, dan pengodean sebagai atribut.

Membaca atribut pada node jenis dokumen

Ketika pembaca XML diposisikan pada node jenis dokumen, GetAttribute metode dan Item[] properti dapat digunakan untuk mengembalikan nilai untuk literal SISTEM dan PUBLIK. Misalnya, panggilan reader.GetAttribute("PUBLIC") mengembalikan nilai PUBLIC.

Membaca atribut pada simpul instruksi pemrosesan

XmlReader Ketika diposisikan pada simpul instruksi pemrosesan, Value properti mengembalikan seluruh konten teks. Item dalam simpul instruksi pemrosesan tidak diperlakukan sebagai atribut. Mereka tidak dapat dibaca dengan GetAttribute metode atau MoveToAttribute .

Membaca konten XML

Kelas XmlReader menyertakan anggota berikut yang membaca konten dari file XML dan mengembalikan konten sebagai nilai string. (Untuk mengembalikan jenis CLR, lihat Konversi ke jenis CLR.)

Gunakan anggota ini XmlReader Untuk
Properti Value Dapatkan konten teks dari simpul saat ini. Nilai yang dikembalikan tergantung pada jenis node; Value lihat halaman referensi untuk detailnya.
metode ReadString Dapatkan konten elemen atau node teks sebagai string. Metode ini berhenti memproses instruksi dan komentar.

Untuk detail tentang cara metode ini menangani jenis node tertentu, lihat ReadString halaman referensi.
Metode ReadInnerXml dan ReadInnerXmlAsync Dapatkan semua konten simpul saat ini, termasuk markup, tetapi tidak termasuk tag mulai dan akhir. Misalnya, untuk:

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

ReadInnerXml menghasilkan:

this<child id="123"/>
Metode ReadOuterXml dan ReadOuterXmlAsync Dapatkan semua konten simpul saat ini dan turunannya, termasuk tag markup dan start/end. Misalnya, untuk:

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

ReadOuterXml menghasilkan:

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

Mengonversi ke jenis CLR

Anda dapat menggunakan anggota XmlReader kelas (tercantum dalam tabel berikut) untuk membaca data XML dan mengembalikan nilai sebagai jenis runtime bahasa umum (CLR) alih-alih string. Anggota ini memungkinkan Anda untuk mendapatkan nilai dalam representasi yang paling sesuai untuk tugas pengkodan Anda tanpa harus mengurai atau mengonversi nilai string secara manual.

  • Metode ReadElementContentAs hanya dapat dipanggil pada jenis node elemen. Metode ini tidak dapat digunakan pada elemen yang berisi elemen turunan atau konten campuran. Saat dipanggil XmlReader , objek membaca tag mulai, membaca konten elemen, lalu bergerak melewati tag elemen akhir. Instruksi pemrosesan dan komentar diabaikan dan entitas diperluas.

  • Metode ReadContentAs membaca konten teks pada posisi pembaca saat ini, dan jika data XML tidak memiliki skema atau informasi tipe data yang terkait dengannya, konversikan konten teks ke jenis pengembalian yang diminta. Teks, spasi kosong, ruang kosong yang signifikan, dan bagian CDATA digabungkan. Instruksi komentar dan pemrosesan dilewati, dan referensi entitas diselesaikan secara otomatis.

Kelas XmlReader menggunakan aturan yang ditentukan oleh rekomendasi Skema XML W3C Bagian 2: Jenis data .

Gunakan metode ini XmlReader Untuk mengembalikan jenis CLR ini
ReadContentAsBoolean dan ReadElementContentAsBoolean Boolean
ReadContentAsDateTime dan ReadElementContentAsDateTime DateTime
ReadContentAsDouble dan ReadElementContentAsDouble Double
ReadContentAsLong dan ReadElementContentAsLong Int64
ReadContentAsInt dan ReadElementContentAsInt Int32
ReadContentAsString dan ReadElementContentAsString String
ReadContentAs dan ReadElementContentAs Jenis yang Anda tentukan returnType dengan parameter
ReadContentAsObject dan ReadElementContentAsObject Jenis yang paling tepat, seperti yang ditentukan oleh XmlReader.ValueType properti . Lihat Ketik Dukungan di Kelas System.Xml untuk informasi pemetaan.

Jika elemen tidak dapat dengan mudah dikonversi ke jenis CLR karena formatnya, Anda dapat menggunakan pemetaan skema untuk memastikan konversi berhasil. Contoh berikut menggunakan file .xsd untuk mengonversi hire-date elemen ke xs:date jenis , lalu menggunakan ReadElementContentAsDateTime metode untuk mengembalikan elemen sebagai DateTime objek.

Input (hireDate.xml):

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

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

Kode:

// 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: {0}", 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

Output:

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

Pemrograman asinkron

Sebagian XmlReader besar metode memiliki rekan asinkron yang memiliki "Asinkron" di akhir nama metode mereka. Misalnya, setara ReadContentAsObject asinkron adalah ReadContentAsObjectAsync.

Metode berikut dapat digunakan dengan panggilan metode asinkron:

Bagian berikut menjelaskan penggunaan asinkron untuk metode yang tidak memiliki rekan asinkron.

Metode 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

Metode 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

Metode 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

Metode ReadToFollowing

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

Metode 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

Pertimbangan keamanan

Pertimbangkan hal berikut saat bekerja dengan XmlReader kelas :

  • Pengecualian yang dilemparkan dari XmlReader dapat mengungkapkan informasi jalur yang mungkin tidak ingin Anda gelembungkan ke aplikasi Anda. Aplikasi Anda harus menangkap pengecualian dan memprosesnya dengan tepat.

  • Jangan aktifkan pemrosesan DTD jika Anda khawatir tentang penolakan masalah layanan atau jika Anda berurusan dengan sumber yang tidak tepercaya. Pemrosesan DTD dinonaktifkan secara default untuk XmlReader objek yang dibuat oleh Create metode .

    Jika Anda mengaktifkan pemrosesan DTD, Anda dapat menggunakan XmlSecureResolver untuk membatasi sumber daya yang XmlReader dapat diakses. Anda juga dapat merancang aplikasi sehingga pemrosesan XML dibatasi memori dan waktu. Misalnya, Anda dapat mengonfigurasi batas waktu habis di aplikasi ASP.NET Anda.

  • Data XML dapat menyertakan referensi ke sumber daya eksternal seperti file skema. Secara default, sumber daya eksternal diselesaikan dengan menggunakan XmlUrlResolver objek tanpa kredensial pengguna. Anda dapat mengamankannya lebih lanjut dengan melakukan salah satu hal berikut:

  • Bendera ProcessInlineSchemaXmlReaderSettings validasi dan ProcessSchemaLocation objek tidak diatur secara default. Ini membantu melindungi XmlReader dari serangan berbasis skema saat memproses data XML dari sumber yang tidak tepercaya. Ketika bendera ini diatur, XmlResolver objek XmlReaderSettings digunakan untuk menyelesaikan lokasi skema yang ditemui dalam dokumen instans di XmlReader. XmlResolver Jika properti diatur ke null, lokasi skema tidak diselesaikan meskipun ProcessInlineSchema bendera validasi dan ProcessSchemaLocation diatur.

    Skema yang ditambahkan selama validasi menambahkan jenis baru dan dapat mengubah hasil validasi dokumen yang sedang divalidasi. Akibatnya, skema eksternal hanya boleh diselesaikan dari sumber tepercaya.

    Sebaiknya nonaktifkan ProcessIdentityConstraints bendera saat memvalidasi dokumen XML besar yang tidak tepercaya dalam skenario ketersediaan tinggi terhadap skema yang memiliki batasan identitas pada sebagian besar dokumen. Bendera ini diaktifkan secara default.

  • Data XML dapat berisi sejumlah besar atribut, deklarasi namespace, elemen berlapis dan sebagainya yang memerlukan banyak waktu untuk diproses. Untuk membatasi ukuran input yang dikirim ke XmlReader, Anda dapat:

  • Metode ini ReadValueChunk dapat digunakan untuk menangani aliran data yang besar. Metode ini membaca sejumlah kecil karakter pada satu waktu alih-alih mengalokasikan string tunggal untuk seluruh nilai.

  • Saat membaca dokumen XML dengan sejumlah besar nama lokal, namespace, atau awalan unik, masalah dapat terjadi. Jika Anda menggunakan kelas yang berasal dari XmlReader, dan Anda memanggil LocalNameproperti , , Prefixatau NamespaceURI untuk setiap item, string yang dikembalikan ditambahkan ke NameTable. Koleksi yang dipegang oleh ukuran yang NameTable tidak pernah berkurang, menciptakan kebocoran memori virtual dari handel string. Salah satu mitigasi untuk ini adalah berasal dari NameTable kelas dan memberlakukan kuota ukuran maksimum. (Tidak ada cara untuk mencegah penggunaan NameTable, atau untuk mengalihkan NameTable saat penuh). Mitigasi lain adalah menghindari penggunaan properti yang disebutkan dan sebaliknya menggunakan MoveToAttribute metode dengan metode jika IsStartElement memungkinkan; metode tersebut tidak mengembalikan string dan dengan demikian menghindari masalah pengisian NameTable koleksi yang berlebihan.

  • XmlReaderSettings objek dapat berisi informasi sensitif seperti kredensial pengguna. Komponen yang tidak tepercaya dapat menggunakan XmlReaderSettings objek dan kredensial penggunanya untuk membuat XmlReader objek untuk membaca data. Berhati-hatilah saat penembolokan XmlReaderSettings objek, atau saat meneruskan XmlReaderSettings objek dari satu komponen ke komponen lainnya.

  • Jangan menerima komponen pendukung, seperti NameTable, , XmlNamespaceManagerdan XmlResolver objek, dari sumber yang tidak tepercaya.