Bagikan melalui


Kelas System.Xml.XmlReader

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

XmlReader menyediakan akses searah dan baca-saja ke data XML dalam dokumen atau stream. Kelas ini sesuai dengan rekomendasi dari W3C Extensible Markup Language (XML) 1.0 (edisi keempat) dan Namespaces di XML 1.0 (edisi ketiga).

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

XmlReader menggunakan model penarikan untuk mengambil data. Model ini:

  • Menyederhanakan pengelolaan status melalui penyempurnaan prosedural yang alami dan berorientasi 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 yang relevan untuk aplikasi. Anda juga dapat mengatur properti terlebih dahulu untuk mengelola bagaimana aliran XML diproses (misalnya, normalisasi).

Membuat pembaca XML

Gunakan metode Create untuk membuat instans XmlReader.

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

  • Saat Anda ingin membaca subtree XML DOM dari objek XmlNode, gunakan kelas XmlNodeReader. (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 kelas XmlTextReader.

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

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

XmlReader menghasilkan XmlException pada kesalahan 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. Gunakan properti ReadState untuk memeriksa apakah pembaca dalam status kesalahan.

Memvalidasi langsung 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: Tipe data rekomendasi.) 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 disimpan dalam objek XmlSchemaSet (cache); skenario ini dijelaskan di halaman referensi Create. XmlReader tidak mendukung validasi skema XML-Data Reduced (XDR).

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

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

- AllowXmlAttributes-- Izinkan atribut XML (xml:*) dalam dokumen instans bahkan ketika tidak ditentukan dalam skema. Atribut divalidasi berdasarkan jenis datanya. Lihat halaman referensi XmlSchemaValidationFlags untuk pengaturan yang akan digunakan dalam skenario tertentu. (Dinonaktifkan secara default.)
- ProcessIdentityConstraints --Memproses batasan identitas (xs:ID, xs:IDREF, xs:key, xs:keyref, xs:unique) yang ditemui selama validasi. (Diaktifkan secara default.)
- ProcessSchemaLocation --Proses skema yang ditentukan oleh atribut xsi:schemaLocation 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 XmlSchemaSet yang digunakan dalam proses validasi.
XmlResolver Properti XmlResolver untuk menyelesaikan dan mengakses sumber daya eksternal. Ini dapat mencakup entitas eksternal seperti DTD dan skema, dan elemen xs:include atau xs:import apa pun yang terkandung dalam Skema XML. Jika Anda tidak menentukan XmlResolver, XmlReader menggunakan XmlUrlResolver default tanpa kredensial pengguna.

Kesuaian data

Pembaca XML yang dibuat oleh metode Create 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.

  • Diizinkan untuk mendeklarasikan awalan XML yang dipetakan ke URI namespace XML yang benar.

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

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

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

- Karakter berada dalam rentang karakter XML sah, sebagaimana yang didefinisikan dalam bagian 2.2 Karakter dari Rekomendasi XML W3C 1.0.
- Semua nama XML valid, seperti yang didefinisikan oleh 2.3 Common Syntactic Constructs bagian dari Rekomendasi XML W3C 1.0.

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

Mengatur CheckCharacters ke 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), XmlException dilemparkan.
ConformanceLevel Properti 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 diurai eksternal.
- Auto. Sesuai dengan tingkat yang diputuskan oleh pembaca.

Jika data tidak sesuai, pengecualian XmlException akan dilemparkan.
Document

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

Metode berikut memudahkan untuk menavigasi melalui simpul dan mengurai data.

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

Gunakan properti NodeType untuk mendapatkan jenis (misalnya, atribut, komentar, elemen, dan sebagainya) dari simpul saat ini.
Skip Lewati anak-anak dari 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 mencakup ProcessingInstruction, DocumentType, Comment, Whitespace, dan SignificantWhitespace.

Node konten mencakup teks spasi non-putih, CDATA, EntityReference , dan EndEntity.
ReadSubtree Baca elemen dan semua turunannya, dan kembalikan instans XmlReader baru yang ditetapkan 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.

Lihat halaman referensi XmlReader.Read 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 disediakan kelas XmlReader untuk elemen pemrosesan. Setelah XmlReader diposisikan pada elemen, properti simpul, seperti Name, mencerminkan nilai elemen. Selain anggota yang dijelaskan di bawah ini, salah satu metode umum dan properti kelas XmlReader juga dapat digunakan untuk memproses elemen. Misalnya, Anda dapat menggunakan metode ReadInnerXml untuk membaca konten elemen.

Nota

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

Gunakan anggota XmlReader ini 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 anak berikutnya yang memiliki nama yang ditentukan.
metode ReadToNextSibling Lanjutkan pembaca XML ke elemen saudara kandung berikutnya yang memiliki nama yang ditentukan.
IsEmptyElement Properti Periksa apakah elemen saat ini memiliki tag elemen akhir. Contohnya:

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

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

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

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, metode MoveToAttribute memungkinkan Anda melalui daftar atribut elemen. Perhatikan bahwa setelah MoveToAttribute dipanggil, properti simpul seperti Name, NamespaceURI, dan Prefix mencerminkan properti atribut tersebut, bukan properti elemen tempat atribut berada.

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

Gunakan anggota XmlReader ini Untuk
HasAttributes Properti Periksa apakah simpul saat ini memiliki atribut apa pun.
AttributeCount Properti 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.
metode GetAttribute atau properti Item[] Dapatkan nilai atribut tertentu.
IsDefault Properti 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 node Text, EntityReference, atau EndEntity.

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

Contoh ini menggunakan properti AttributeCount 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($"  {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 metode MoveToNextAttribute dalam perulangan while untuk menavigasi melalui atribut.

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

Membaca atribut pada simpul deklarasi XML

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

Membaca atribut pada node jenis dokumen

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

Membaca atribut pada node instruksi pemrosesan

Saat XmlReader diposisikan pada simpul instruksi pemrosesan, properti Value mengembalikan seluruh konten teks. Item dalam simpul instruksi pemrosesan tidak diperlakukan sebagai atribut. Mereka tidak dapat dibaca dengan metode GetAttribute 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 XmlReader ini Untuk
Value Properti Dapatkan konten teks dari simpul saat ini. Nilai yang dikembalikan tergantung pada jenis node; lihat halaman referensi Value 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 halaman referensi ReadString.
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 tipe CLR

Anda dapat menggunakan anggota kelas XmlReader (tercantum dalam tabel berikut) untuk membaca data XML dan mengembalikan nilai sebagai jenis common language runtime (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 anak atau konten campuran. Saat dipanggil, objek XmlReader 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 jenis 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 W3C Skema XML Bagian 2: Tipe Data.

Gunakan metode XmlReader ini Untuk mengembalikan tipe 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 dengan parameter returnType
ReadContentAsObject dan ReadElementContentAsObject Jenis yang paling tepat, seperti yang ditentukan oleh properti XmlReader.ValueType. Lihat Dukungan Jenis 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 elemen hire-date ke jenis xs:date, lalu menggunakan metode ReadElementContentAsDateTime untuk mengembalikan elemen sebagai objek DateTime.

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: {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

Hasil:

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

Pemrograman asinkron

Sebagian besar metode XmlReader memiliki rekan asinkron yang memiliki "Asinkron" di akhir nama metode mereka. Misalnya, setara asinkron dari ReadContentAsObject 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 kelas XmlReader:

  • 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 mengaktifkan pemrosesan DTD jika Anda khawatir akan serangan penolakan layanan atau jika Anda berurusan dengan sumber yang tidak tepercaya. Pemrosesan DTD dinonaktifkan secara default untuk objek XmlReader yang dibuat oleh metode Create.

    Jika Anda mengaktifkan pemrosesan DTD, Anda dapat menggunakan XmlSecureResolver untuk membatasi sumber daya yang dapat diakses XmlReader. 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 objek XmlUrlResolver tanpa kredensial pengguna. Anda dapat mengamankannya lebih lanjut dengan melakukan salah satu hal berikut:

  • Bendera validasi ProcessInlineSchema dan ProcessSchemaLocation objek XmlReaderSettings tidak diatur secara default. Ini membantu melindungi XmlReader dari serangan berbasis skema saat memproses data XML dari sumber yang tidak tepercaya. Ketika parameter ini diatur, XmlResolver dari objek XmlReaderSettings digunakan untuk menentukan lokasi skema yang ditemukan dalam dokumen instance pada XmlReader. Jika properti XmlResolver diatur ke null, lokasi skema tidak akan ditentukan meskipun tanda validasi ProcessInlineSchema 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 bendera ProcessIdentityConstraints 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 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 properti LocalName, Prefix, atau NamespaceURI untuk setiap item, string yang dikembalikan ditambahkan ke NameTable. Koleksi yang dipegang oleh NameTable tidak pernah berkurang ukurannya, menciptakan kebocoran memori virtual dari pegangan string. Salah satu mitigasi untuk ini adalah berasal dari kelas NameTable dan memberlakukan kuota ukuran maksimum. (Tidak ada cara untuk mencegah penggunaan NameTable, atau untuk mengalihkan NameTable ketika penuh). Mitigasi lain adalah menghindari penggunaan properti yang disebutkan dan sebaliknya menggunakan metode MoveToAttribute dengan metode IsStartElement jika memungkinkan; metode tersebut tidak mengembalikan string dan dengan demikian menghindari masalah overfilling koleksi NameTable.

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

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