System.Xml.XmlReader – třída
Tento článek obsahuje doplňující poznámky k referenční dokumentaci pro toto rozhraní API.
XmlReader poskytuje přístup k datům XML v dokumentu nebo datovém proudu jen pro čtení. Tato třída odpovídá standardu W3C Extensible Markup Language (XML) 1.0 (čtvrtá edice) a oborů názvů v doporučeních XML 1.0 (třetí edice).
XmlReader metody umožňují procházet data XML a číst obsah uzlu. Vlastnosti třídy odrážejí hodnotu aktuálního uzlu, kde je čtenář umístěn. Hodnota ReadState vlastnosti označuje aktuální stav čtečky XML. Například vlastnost je nastavena ReadState.Initial metodou XmlReader.Read a ReadState.Closed metodou XmlReader.Close . XmlReader poskytuje také kontroly a ověřování shody dat s DTD nebo schématem.
XmlReader používá model vyžádané replikace k načtení dat. Tento model:
- Zjednodušuje správu stavu přirozeným procedurálním upřesněním shora dolů.
- Podporuje více vstupních datových proudů a vrstvení.
- Umožňuje klientovi dát analyzátoru vyrovnávací paměť, do které je řetězec přímo zapsán, a tím se vyhnout nutnosti dodatečné kopie řetězce.
- Podporuje selektivní zpracování. Klient může přeskočit položky a zpracovat ty, které jsou pro aplikaci zajímavé. Můžete také nastavit vlastnosti předem a spravovat způsob zpracování datového proudu XML (například normalizace).
Vytvoření čtečky XML
Použijte metodu CreateXmlReader k vytvoření instance.
I když .NET poskytuje konkrétní implementace XmlReader třídy, například XmlTextReader, XmlNodeReadera XmlValidatingReader třídy, doporučujeme používat specializované třídy pouze v těchto scénářích:
- Pokud chcete číst podstrom XML DOM z objektu XmlNode , použijte XmlNodeReader třídu. (Tato třída ale nepodporuje ověřování DTD ani schématu.)
- Pokud je nutné rozšířit entity na vyžádání, nechcete, aby byl textový obsah normalizován nebo nechcete, aby se vrátily výchozí atributy, použijte XmlTextReader třídu.
Chcete-li zadat sadu funkcí, které chcete povolit pro čtečku XML, předejte System.Xml.XmlReaderSettings objekt metodě Create . Jeden System.Xml.XmlReaderSettings objekt můžete použít k vytvoření více čtenářů se stejnou funkcí nebo úpravou objektu System.Xml.XmlReaderSettings a vytvořit novou čtečku s jinou sadou funkcí. Do existujícího čtenáře můžete také snadno přidávat funkce.
Pokud objekt nepoužíváte System.Xml.XmlReaderSettings , použijí se výchozí nastavení. Podrobnosti najdete na Create referenční stránce.
XmlReaderXmlException vyvolá chybu analýzy XML. Po vyvolání výjimky není stav čtenáře předvídatelný. Například hlášený typ uzlu se může lišit od skutečného typu uzlu aktuálního uzlu. ReadState Pomocí vlastnosti zkontrolujte, jestli je čtenář v chybovém stavu.
Ověření dat XML
Chcete-li definovat strukturu dokumentu XML a jeho relací prvků, datových typů a omezení obsahu, použijete schéma definice typu dokumentu (DTD) nebo XSD (XML Schema Definition Language). Dokument XML je považován za dobře vytvořený, pokud splňuje všechny syntaktické požadavky definované doporučením W3C XML 1.0. Je považována za platnou, pokud je správně vytvořená a také odpovídá omezením definovaným jeho DTD nebo schématem. (Viz Schéma XML W3C – část 1: Struktury a schéma XML W3C – část 2: Doporučení datových typů.) Proto i když jsou všechny platné dokumenty XML dobře formátovány, nejsou všechny dobře formátované dokumenty XML platné.
Data můžete ověřit pomocí DTD, vloženého schématu XSD nebo schématu XSD uloženého XmlSchemaSet v objektu (mezipaměti). Tyto scénáře jsou popsány na Create referenční stránce. XmlReader nepodporuje ověřování schématu XDR (XML-Data Reduced).
Následující nastavení třídy XmlReaderSettings slouží k určení typu ověření, pokud existuje, XmlReader instance podporuje.
Použít tohoto XmlReaderSettings člena | Určení |
---|---|
DtdProcessing Vlastnost | Určuje, jestli se má povolit zpracování DTD. Výchozí hodnota je zakázat zpracování DTD. |
ValidationType Vlastnost | Určuje, jestli má čtenář ověřovat data a jaký typ ověření má provést (DTD nebo schéma). Výchozí hodnota není ověření dat. |
ValidationEventHandler Událost | Obslužná rutina události pro příjem informací o událostech ověření. Pokud obslužná rutina události není zadána, XmlException vyvolá se při první chybě ověření. |
ValidationFlags Vlastnost | Další možnosti ověřování prostřednictvím členů výčtu XmlSchemaValidationFlags : - AllowXmlAttributes -- Povolí atributy XML (xml:* ) v dokumentech instancí, i když nejsou definovány ve schématu. Atributy se ověřují na základě jejich datového typu. XmlSchemaValidationFlags Na stránce s referenčními informacemi najdete nastavení, které se má použít v konkrétních scénářích. (Ve výchozím nastavení je zakázáno.)- ProcessIdentityConstraints --Procesní omezení identity (xs:ID , xs:IDREF , xs:key , xs:keyref , xs:unique ) zjištěna během ověřování. (Ve výchozím nastavení povoleno.)- ProcessSchemaLocation --Process schémata určená atributem nebo xsi:noNamespaceSchemaLocation atributemxsi:schemaLocation . (Ve výchozím nastavení povoleno.)- ProcessInlineSchema -- Zpracování vložených schémat XML během ověřování. (Ve výchozím nastavení je zakázáno.)- ReportValidationWarnings --Report events if a validation warning. Upozornění se obvykle vydává, pokud neexistuje žádné schéma DTD nebo XML k ověření konkrétního elementu nebo atributu. Slouží ValidationEventHandler k oznámení. (Ve výchozím nastavení je zakázáno.) |
Schemas | Slouží XmlSchemaSet k ověření. |
XmlResolver Vlastnost | Řešení XmlResolver a přístup k externím prostředkům. To může zahrnovat externí entity, jako jsou DTD a schémata, a všechny xs:include nebo xs:import prvky obsažené ve schématu XML. Pokud ho nezadáte XmlResolver, XmlReader použije se výchozí XmlUrlResolver hodnota bez přihlašovacích údajů uživatele. |
Shoda s daty
Čtečky XML vytvořené metodou Create splňují následující požadavky na dodržování předpisů ve výchozím nastavení:
Nové řádky a hodnota atributu jsou normalizovány podle doporučení W3C XML 1.0.
Všechny entity se automaticky rozbalí.
Výchozí atributy deklarované v definici typu dokumentu se vždy přidají i v případě, že čtenář neověří.
Deklarace předpony XML namapované na správný identifikátor URI oboru názvů XML je povolena.
Názvy notací v deklaraci jednoho
NotationType
atributu aNmTokens
v deklaraci jednohoEnumeration
atributu jsou odlišné.
Pomocí těchto XmlReaderSettings vlastností určete typ kontrol shody, které chcete povolit:
Použít tuto XmlReaderSettings vlastnost | To | Výchozí |
---|---|---|
CheckCharacters Vlastnost | Povolte nebo zakažte kontroly následujících: - Znaky jsou v rozsahu právních znaků XML, jak je definováno oddílem 2,2 Znaků v doporučení W3C XML 1.0. - Všechny názvy XML jsou platné, jak je definováno oddílem 2.3 Společné syntaktické konstruktory v doporučení W3C XML 1.0. Pokud je tato vlastnost nastavena na true (výchozí), vyvolá XmlException se výjimka, pokud soubor XML obsahuje neplatné znaky nebo neplatné názvy XML (například název elementu začíná číslem). |
Je povolená kontrola znaků a názvů. Nastavení CheckCharacters pro false vypnutí kontroly znaků u odkazů na entitu znaků Pokud čtečka zpracovává textová data, vždy zkontroluje platnost názvů XML bez ohledu na toto nastavení. Poznámka: Doporučení XML 1.0 vyžaduje shodu na úrovni dokumentu, pokud je k dispozici DTD. Proto pokud je čtečka nakonfigurována tak, aby podporovala ConformanceLevel.Fragment, ale data XML obsahují definici typu dokumentu (DTD), XmlException je vyvolán. |
ConformanceLevel Vlastnost | Zvolte úroveň shody, která se má vynutit: - Document. Odpovídá pravidlům pro dokument XML 1.0 ve správném formátu. - Fragment. Odpovídá pravidlům pro dobře formátovaný fragment dokumentu, který lze použít jako externí analyzovanou entitu. - Auto. Odpovídá úrovni, o které rozhoduje čtenář. Pokud data neodpovídají, vyvolá XmlException se výjimka. |
Document |
Procházení uzlů
Aktuální uzel je uzel XML, na kterém je aktuálně umístěna čtečka XML. Všechny XmlReader metody provádějí operace ve vztahu k tomuto uzlu a všechny XmlReader vlastnosti odrážejí hodnotu aktuálního uzlu.
Následující metody usnadňují procházení uzlů a parsování dat.
Použít tuto XmlReaderSettings metodu | To |
---|---|
Read | Přečtěte si první uzel a projděte si stream po jednom uzlu. Taková volání se obvykle provádějí uvnitř while smyčky.NodeType Pomocí vlastnosti získejte typ (například atribut, komentář, element atd.) aktuálního uzlu. |
Skip | Přeskočte podřízené položky aktuálního uzlu a přejděte na další uzel. |
MoveToContent a MoveToContentAsync | Přeskočte uzly bez obsahu a přejděte na další uzel obsahu nebo na konec souboru. Mezi uzly, které nejsou obsahem, patří ProcessingInstruction, DocumentTypeComment, Whitespace, a SignificantWhitespace. Mezi uzly obsahu patří text, který není prázdný, CDATAEntityReference a EndEntity. |
ReadSubtree | Přečtěte si prvek a všechny jeho podřízené položky a vraťte novou XmlReader instanci nastavenou na ReadState.Initial. Tato metoda je užitečná pro vytváření hranic kolem elementů XML; Pokud například chcete předat data jiné komponentě ke zpracování a chcete omezit, kolik dat má komponenta přístup. |
Podívejte se na XmlReader.Read referenční stránku, kde najdete příklad procházení textového streamu po jednom uzlu a zobrazení typu každého uzlu.
Následující části popisují, jak můžete číst konkrétní typy dat, jako jsou prvky, atributy a typová data.
Čtení elementů XML
Následující tabulka uvádí metody a vlastnosti, které XmlReader třída poskytuje pro zpracování prvků. XmlReader Po umístění prvku vlastnosti uzlu, například Name, odrážejí hodnoty elementu. Kromě níže popsaných členů lze k zpracování prvků použít také některou z obecných metod a vlastností XmlReader třídy. Můžete například použít metodu ReadInnerXml ke čtení obsahu elementu.
Poznámka:
Viz část 3.1 doporučení XML W3C 1.0 pro definice počátečních značek, koncových značek a prázdných značek elementů.
Použít tohoto XmlReader člena | To |
---|---|
IsStartElement Metoda | Zkontrolujte, jestli je aktuální uzel počáteční značkou nebo prázdnou značkou elementu. |
ReadStartElement Metoda | Zkontrolujte, jestli je aktuální uzel prvkem, a přejděte čtenáře na další uzel (volání IsStartElement následovaná Read). |
ReadEndElement Metoda | Zkontrolujte, jestli je aktuální uzel koncovou značkou, a přejděte čtenáře na další uzel. |
ReadElementString Metoda | Čtení textového elementu |
ReadToDescendant Metoda | Přejděte do dalšího potomka (podřízeného) elementu, který má zadaný název. |
ReadToNextSibling Metoda | Přejděte čtečku XML na další prvek na stejné straně, který má zadaný název. |
IsEmptyElement Vlastnost | Zkontrolujte, jestli má aktuální prvek značku koncového prvku. Příklad: - <item num="123"/> (IsEmptyElement je true .)- <item num="123"> </item> (IsEmptyElement je false , i když obsah prvku je prázdný.) |
Příklad čtení textového obsahu prvků naleznete v ReadString metodě. Následující příklad zpracovává prvky pomocí smyčky 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
Čtení atributů XML
Atributy XML se nejčastěji vyskytují u elementů, ale jsou také povoleny u deklarací XML a uzlů typu dokumentu.
Při umístění na uzlu elementu MoveToAttribute umožňuje metoda projít seznam atributů elementu. Všimněte si, že po MoveToAttribute zavolání, vlastnosti uzlu, jako Nameje , NamespaceURIa Prefix odrážejí vlastnosti tohoto atributu, nikoli vlastnosti prvku, ke kterému atribut patří.
Třída XmlReader poskytuje tyto metody a vlastnosti pro čtení a zpracování atributů prvků.
Použít tohoto XmlReader člena | To |
---|---|
HasAttributes Vlastnost | Zkontrolujte, jestli má aktuální uzel nějaké atributy. |
AttributeCount Vlastnost | Získejte počet atributů pro aktuální prvek. |
MoveToFirstAttribute Metoda | Přechod na první atribut v elementu |
MoveToNextAttribute Metoda | Přechod na další atribut v elementu |
MoveToAttribute Metoda | Přechod na zadaný atribut |
GetAttribute metoda nebo Item[] vlastnost | Získá hodnotu zadaného atributu. |
IsDefault Vlastnost | Zkontrolujte, jestli je aktuální uzel atributem vygenerovaným z výchozí hodnoty definované v DTD nebo schématu. |
MoveToElement Metoda | Přechod na prvek, který vlastní aktuální atribut. Tuto metodu použijte k návratu k prvku po procházení jeho atributů. |
ReadAttributeValue Metoda | Parsujte hodnotu atributu do jednoho nebo více Text uzlů EntityReference nebo EndEntity uzlů. |
Všechny obecné XmlReader metody a vlastnosti lze také použít ke zpracování atributů. Například po umístění atributu XmlReaderName a Value vlastnosti odrážejí hodnoty atributu. K získání hodnoty atributu můžete použít také některou z metod obsahu Read
.
Tento příklad používá AttributeCount vlastnost k procházení všech atributů v elementu.
// 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
Tento příklad používá metodu MoveToNextAttributewhile
ve smyčce k procházení 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
Čtení atributů v uzlech deklarace XML
Když je čtečka XML umístěna na uzlu deklarace XML, Value vrátí vlastnost informace o verzi, samostatné a kódování jako jeden řetězec. XmlReader objekty vytvořené metodou Create , XmlTextReader třídou a XmlValidatingReader třídou zpřístupňují verzi, samostatnou a kódovací položky jako atributy.
Čtení atributů na uzlech typu dokumentu
Pokud je čtečka XML umístěna na uzlu typu dokumentu, lze metodu GetAttribute a Item[] vlastnost použít k vrácení hodnot pro SYSTÉM a VEŘEJNÉ literály. Volání například reader.GetAttribute("PUBLIC")
vrátí hodnotu PUBLIC.
Čtení atributů při zpracování uzlů instrukcí
Když je umístěn na XmlReader zpracování instrukční uzel, Value vrátí vlastnost celý textový obsah. Položky v uzlu instrukce zpracování nejsou považovány za atributy. Nelze je přečíst pomocí GetAttribute metody ani MoveToAttribute metody.
Čtení obsahu XML
XmlReader třída obsahuje následující členy, které čtou obsah ze souboru XML a vrací obsah jako řetězcové hodnoty. (Informace o vrácení typů CLR najdete v tématu Převést na typy CLR.)
Použít tohoto XmlReader člena | To |
---|---|
Value Vlastnost | Získá textový obsah aktuálního uzlu. Vrácená hodnota závisí na typu uzlu; Podrobnosti najdete na Value stránce s referenčními informacemi. |
ReadString Metoda | Získá obsah prvku nebo textového uzlu jako řetězec. Tato metoda zastaví zpracování pokynů a komentářů. Podrobnosti o tom, jak tato metoda zpracovává konkrétní typy uzlů, najdete na ReadString referenční stránce. |
ReadInnerXml a ReadInnerXmlAsync metody | Získejte veškerý obsah aktuálního uzlu, včetně značek, ale s výjimkou počátečních a koncových značek. Například pro:<node>this<child id="123"/></node> ReadInnerXml Vrátí: this<child id="123"/> |
ReadOuterXml a ReadOuterXmlAsync metody | Získejte veškerý obsah aktuálního uzlu a jeho podřízených položek, včetně značek a značek start/end. Například pro:<node>this<child id="123"/></node> ReadOuterXml Vrátí: <node>this<child id="123"/></node> |
Převod na typy CLR
Členy XmlReader třídy (uvedené v následující tabulce) můžete použít ke čtení dat XML a vrácení hodnot jako typů CLR (Common Language Runtime) místo řetězců. Tito členové umožňují získat hodnoty v reprezentaci, která je nejvhodnější pro úkol kódování, aniž byste museli ručně parsovat nebo převést řetězcové hodnoty.
Metody ReadElementContentAs lze volat pouze u typů uzlů elementů. Tyto metody nelze použít u prvků, které obsahují podřízené prvky nebo smíšený obsah. Při zavolání XmlReader objekt přečte počáteční značku, přečte obsah elementu a pak se přesune za značku koncového prvku. Pokyny ke zpracování a komentáře se ignorují a entity se rozbalí.
Metody ReadContentAs čtou textový obsah v aktuální pozici čtenáře a pokud data XML nemají přidružené žádné schéma nebo informace o datovém typu, převeďte textový obsah na požadovaný návratový typ. Text, prázdné znaky, významné prázdné znaky a oddíly CDATA jsou zřetězeny. Komentáře a pokyny ke zpracování se přeskočí a odkazy na entity se automaticky přeloží.
Třída XmlReader používá pravidla definovaná schématem XML W3C část 2: Doporučení datových typů.
Použít tuto XmlReader metodu | Vrácení tohoto typu CLR |
---|---|
ReadContentAsBoolean a ReadElementContentAsBoolean | Boolean |
ReadContentAsDateTime a ReadElementContentAsDateTime | DateTime |
ReadContentAsDouble a ReadElementContentAsDouble | Double |
ReadContentAsLong a ReadElementContentAsLong | Int64 |
ReadContentAsInt a ReadElementContentAsInt | Int32 |
ReadContentAsString a ReadElementContentAsString | String |
ReadContentAs a ReadElementContentAs | Typ, který zadáte pomocí parametru returnType |
ReadContentAsObject a ReadElementContentAsObject | Nejvhodnější typ, jak je určeno vlastností XmlReader.ValueType . Informace o mapování naleznete v části Podpora typů v třídách System.Xml. |
Pokud prvek nelze snadno převést na typ CLR z důvodu jeho formátu, můžete použít mapování schématu k zajištění úspěšného převodu. Následující příklad používá soubor .xsd k převodu hire-date
elementu na xs:date
typ a pak používá metodu ReadElementContentAsDateTime k vrácení elementu DateTime jako objektu.
Vstup (hireDate.xml):
<employee xmlns="urn:empl-hire">
<ID>12365</ID>
<hire-date>2003-01-08</hire-date>
<title>Accountant</title>
</employee>
Schéma (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>
Kód:
// 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
Výstup:
Six Month Review Date: 7/8/2003 12:00:00 AM
Asynchronní programování
XmlReader Většina metod má asynchronní protějšky, které mají na konci názvů metod "Async". Například asynchronní ekvivalent ReadContentAsObject je ReadContentAsObjectAsync.
Následující metody lze použít s asynchronními voláními metod:
- GetAttribute
- MoveToAttribute
- MoveToFirstAttribute
- MoveToNextAttribute
- MoveToElement
- ReadAttributeValue
- ReadSubtree
- ResolveEntity
Následující části popisují asynchronní použití metod, které nemají asynchronní protějšky.
Metoda 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
Metoda 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
Metoda 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
Metoda 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
Metoda 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
Bezpečnostní aspekty
Při práci s XmlReader třídou zvažte následující skutečnosti:
Výjimky vyvolané z XmlReader můžou odhalit informace o cestě, které možná nechcete, aby se bubliny zobrazovaly v aplikaci. Vaše aplikace musí zachytit výjimky a odpovídajícím způsobem je zpracovat.
Nepovolujte zpracování DTD, pokud máte obavy o problémy s odepřením služeb nebo pokud pracujete s nedůvěryhodnými zdroji. Zpracování DTD je ve výchozím nastavení zakázané pro XmlReader objekty vytvořené metodou Create .
Pokud máte povolené zpracování DTD, můžete použít XmlSecureResolver omezení prostředků, ke kterým XmlReader má přístup. Aplikaci můžete také navrhnout tak, aby zpracování XML bylo omezené na paměť a čas. V aplikaci ASP.NET můžete například nakonfigurovat limity časového limitu.
Data XML můžou obsahovat odkazy na externí prostředky, jako je soubor schématu. Ve výchozím nastavení se externí prostředky překládají pomocí objektu XmlUrlResolver bez přihlašovacích údajů uživatele. Můžete to dále zabezpečit jedním z následujících způsobů:
Omezte prostředky, ke kterým XmlReader má přístup, nastavením XmlReaderSettings.XmlResolver vlastnosti na XmlSecureResolver objekt.
Nepovolte XmlReader otevření žádných externích prostředků nastavením XmlReaderSettings.XmlResolver vlastnosti na
null
.
Příznaky ProcessInlineSchema ověřování ProcessSchemaLocation objektu XmlReaderSettings nejsou ve výchozím nastavení nastavené. To pomáhá chránit XmlReader před útoky založenými na schématu při zpracování dat XML z nedůvěryhodného zdroje. Při nastavení XmlResolverXmlReaderSettings těchto příznaků se objekt použije k překladu umístění schématu, ke kterým došlo v dokumentu instance v dokumentu instance v objektu XmlReader. XmlResolver Pokud je vlastnost nastavená na
null
, umístění schématu se nevyřeší, i když ProcessInlineSchema jsou nastavené příznaky ověřováníProcessSchemaLocation.Schémata přidaná během ověřování přidávají nové typy a můžou změnit výsledek ověření ověřovaného dokumentu. V důsledku toho by externí schémata měla být vyřešena pouze z důvěryhodných zdrojů.
Doporučujeme zakázat ProcessIdentityConstraints příznak při ověřování nedůvěryhodných a velkých dokumentů XML ve scénářích s vysokou dostupností vůči schématu, které má omezení identit nad velkou částí dokumentu. Tento příznak je ve výchozím nastavení povolený.
Data XML můžou obsahovat velký počet atributů, deklarací oboru názvů, vnořených elementů atd., které vyžadují značné množství času ke zpracování. Chcete-li omezit velikost vstupu odeslaného XmlReaderdo souboru , můžete:
Omezte velikost dokumentu nastavením MaxCharactersInDocument vlastnosti.
Omezte počet znaků, které jsou výsledkem rozbalení entit, nastavením MaxCharactersFromEntities vlastnosti.
Vytvoření vlastní
IStream
implementace pro .XmlReader
Metodu ReadValueChunk lze použít ke zpracování velkých datových proudů. Tato metoda načte malý počet znaků najednou místo přidělení jednoho řetězce pro celou hodnotu.
Při čtení dokumentu XML s velkým počtem jedinečných místních názvů, oborů názvů nebo předpon může dojít k problému. Pokud používáte třídu, která je odvozena od XmlReader, a voláte LocalName, Prefixnebo NamespaceURI vlastnost pro každou položku, vrácený řetězec je přidán do NameTable. Kolekce uchovávané nikdy nezmenšuje NameTable velikost a vytváří virtuální paměť nevracení popisovačů řetězců. Jedním z omezení rizik je odvození od NameTable třídy a vynucení maximální kvóty velikosti. (Neexistuje způsob, jak zabránit použití NameTablenebo přepnout, NameTable když je plný). Dalším zmírněním rizik je vyhnout se použití uvedených vlastností a místo toho použít MoveToAttribute metodu s metodou IsStartElement , pokud je to možné; tyto metody nevrací řetězce, a proto se vyhnete problému přeplnění NameTable kolekce.
XmlReaderSettings objekty mohou obsahovat citlivé informace, jako jsou přihlašovací údaje uživatele. Nedůvěryhodná komponenta může objekt a jeho přihlašovací údaje uživatele použít XmlReaderSettings k vytvoření XmlReader objektů pro čtení dat. Při ukládání objektů do mezipaměti XmlReaderSettings nebo při předávání objektu XmlReaderSettings z jedné komponenty do jiné buďte opatrní.
Nepřijímají podpůrné komponenty, jako NameTablejsou , XmlNamespaceManagera XmlResolver objekty z nedůvěryhodného zdroje.