Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.
XmlReader proporciona acceso de solo avance y de solo lectura a los datos XML de un documento o secuencia. Esta clase se ajusta a las recomendaciones del W3C Extensible Markup Language (XML) 1.0 (cuarta edición) y a las de Namespaces in XML 1.0 (tercera edición).
XmlReader los métodos permiten desplazarse por datos XML y leer el contenido de un nodo. Las propiedades de la clase reflejan el valor del nodo actual, que es donde se coloca el lector. El ReadState valor de propiedad indica el estado actual del lector XML. Por ejemplo, la propiedad se establece en ReadState.Initial por el método XmlReader.Read y en ReadState.Closed por el método XmlReader.Close. XmlReader también proporciona comprobaciones de conformidad de datos y validación conforme a DTD o esquema.
XmlReader usa un modelo de extracción para recuperar datos. Este modelo:
- Simplifica la administración del estado mediante un refinamiento de procedimientos natural y descendente.
- Admite varios flujos de entrada y capas.
- Permite al cliente proporcionar al analizador un búfer en el que se escribe directamente la cadena y, por tanto, evita la necesidad de una copia de cadena adicional.
- Admite el procesamiento selectivo. El cliente puede omitir elementos y procesar los que son de interés para la aplicación. También puede establecer propiedades de antemano para administrar cómo se procesa la secuencia XML (por ejemplo, normalización).
Creación de un lector XML
Use el Create método para crear una XmlReader instancia.
Aunque .NET proporciona implementaciones concretas de la XmlReader clase , como XmlTextReader, XmlNodeReadery las XmlValidatingReader clases, se recomienda usar las clases especializadas solo en estos escenarios:
- Cuando desee leer un subárbol XML DOM de un XmlNode objeto, use la XmlNodeReader clase . (Sin embargo, esta clase no admite DTD ni validación de esquemas).
- Si debe expandir entidades a petición, no desea que el contenido de texto se normalice o no quiera que se devuelvan los atributos predeterminados, use la XmlTextReader clase .
Para especificar el conjunto de características que desea habilitar en el lector XML, pase un System.Xml.XmlReaderSettings objeto al Create método . Puede usar un solo System.Xml.XmlReaderSettings objeto para crear varios lectores con la misma funcionalidad o modificar el System.Xml.XmlReaderSettings objeto para crear un nuevo lector con un conjunto diferente de características. También puede agregar fácilmente características a un lector existente.
Si no usa un System.Xml.XmlReaderSettings objeto , se usa la configuración predeterminada. Consulte la Create página de referencia para obtener más información.
XmlReader lanza una XmlException en caso de errores de análisis XML. Después de iniciar una excepción, el estado del lector no es predecible. Por ejemplo, el tipo de nodo notificado puede ser diferente del tipo de nodo real del nodo actual. Use la ReadState propiedad para comprobar si el lector está en estado de error.
Validación de datos XML
Para definir la estructura de un documento XML y sus relaciones de elemento, tipos de datos y restricciones de contenido, use un esquema de definición de tipo de documento (DTD) o lenguaje de definición de esquemas XML (XSD). Se considera que un documento XML tiene un formato correcto si cumple todos los requisitos sintácticos definidos por la recomendación W3C XML 1.0. Se considera válido si está bien formado y también se ajusta a las restricciones definidas por su DTD o esquema. (Vea la parte 1 del esquema XML de W3C: Estructuras y el esquema XML W3C, parte 2: recomendaciones de tipos de datos ). Por lo tanto, aunque todos los documentos XML válidos están bien formados, no todos los documentos XML bien formados son válidos.
Puede validar los datos con un DTD, un esquema XSD insertado o un esquema XSD almacenado en un XmlSchemaSet objeto (una memoria caché); estos escenarios se describen en la Create página de referencia. XmlReader no admite la validación del esquema XML-Data Reduced (XDR).
Use la siguiente configuración en la XmlReaderSettings clase para especificar qué tipo de validación, si existe, la XmlReader instancia admite.
Usar este miembro de XmlReaderSettings | Para especificar |
---|---|
Propiedad DtdProcessing | Indica si se va a permitir el procesamiento de DTD. El valor predeterminado es no permitir el procesamiento de DTD. |
Propiedad ValidationType | Si el lector debe validar los datos y qué tipo de validación se va a realizar (DTD o esquema). El valor predeterminado es no realizar validación de datos. |
ValidationEventHandler evento | Un controlador de eventos para recibir información sobre eventos de validación. Si no se proporciona un controlador de eventos, se lanza un XmlException en el primer error de validación. |
Propiedad ValidationFlags | Opciones de validación adicionales a través de los miembros de enumeración XmlSchemaValidationFlags: - AllowXmlAttributes -- Permitir atributos XML (xml:* ) en documentos de instancia incluso cuando no están definidos en el esquema. Los atributos se validan en función de su tipo de datos. Consulte la página de referencia de XmlSchemaValidationFlags para ver la configuración que se va a usar en escenarios específicos. (Deshabilitado de forma predeterminada).- ProcessIdentityConstraints --Procesar las restricciones de identidad (xs:ID , xs:IDREF , xs:key , xs:keyref , xs:unique ) encontradas durante la validación. (Habilitado de forma predeterminada).- ProcessSchemaLocation --Procesar esquemas especificados por el atributo xsi:schemaLocation o el atributo xsi:noNamespaceSchemaLocation . (Habilitado de forma predeterminada).- ProcessInlineSchema -- Procesar esquemas XML insertados durante la validación. (Deshabilitado de forma predeterminada).- ReportValidationWarnings --Notificar eventos si se produce una advertencia de validación. Normalmente, se emite una advertencia cuando no hay ningún esquema DTD o XML para validar un elemento o atributo concretos.
ValidationEventHandler se usa para la notificación. (Deshabilitado de forma predeterminada). |
Schemas | XmlSchemaSet que se va a usar para validación. |
Propiedad XmlResolver |
XmlResolver para resolver y acceder a recursos externos. Esto puede incluir entidades externas, como DTD y esquemas, y cualquier xs:include elemento o xs:import contenido en el esquema XML. Si no especifica un XmlResolver, usa XmlReader un valor predeterminado XmlUrlResolver sin credenciales de usuario. |
Conformidad de datos
Los lectores XML creados por el Create método cumplen los siguientes requisitos de cumplimiento de forma predeterminada:
Las nuevas líneas y el valor de atributo se normalizan según la recomendación W3C XML 1.0.
Todas las entidades se expanden automáticamente.
Los atributos predeterminados declarados en la definición de tipo de documento siempre se añaden incluso cuando no se realiza la validación por el lector.
Se permite la declaración del prefijo XML asignado al URI de espacio de nombres XML correcto.
Los nombres de notación de una sola
NotationType
declaración de atributo yNmTokens
en una declaración de atributo únicoEnumeration
son distintos.
Use estas XmlReaderSettings propiedades para especificar el tipo de comprobaciones de conformidad que desea habilitar:
Use esta XmlReaderSettings propiedad | En | Predeterminado |
---|---|---|
Propiedad CheckCharacters | Habilite o deshabilite las comprobaciones siguientes: - Los caracteres están dentro del intervalo de caracteres XML legales, tal como se define en la sección 2.2 Caracteres de la Recomendación W3C XML 1.0. - Todos los nombres XML son válidos, tal como se define en la sección 2.3 Construcciones sintácticas comunes de la recomendación W3C XML 1.0. Cuando esta propiedad se establece true en (valor predeterminado), se produce una XmlException excepción si el archivo XML contiene caracteres no válidos o nombres XML no válidos (por ejemplo, un nombre de elemento comienza con un número). |
La comprobación de caracteres y nombres está habilitada. Al establecer CheckCharacters en false se desactiva la comprobación de caracteres para las referencias de entidad de caracteres. Si el lector está procesando datos de texto, siempre comprueba que los nombres XML son válidos, independientemente de esta configuración.
Nota: La recomendación XML 1.0 requiere conformidad de nivel de documento cuando hay una DTD presente. Por lo tanto, si el lector está configurado para admitir ConformanceLevel.Fragment, pero los datos XML contienen una definición de tipo de documento (DTD), se lanza un XmlException. |
Propiedad ConformanceLevel | Elija el nivel de conformidad para aplicar: - Document. Se ajusta a las reglas de un documento XML 1.0 bien formado. - Fragment. Se ajusta a las normas para un fragmento de documento bien formado que puede consumirse como una entidad externa analizada. - Auto. Se ajusta al nivel decidido por el lector. Si los datos no son conformes, se produce una XmlException excepción. |
Document |
Navegar por los nodos
El nodo actual es el nodo XML en el que está colocado actualmente el lector XML. Todos los XmlReader métodos realizan operaciones en relación con este nodo y todas las XmlReader propiedades reflejan el valor del nodo actual.
Los métodos siguientes facilitan la navegación por los nodos y analizar los datos.
Use este XmlReaderSettings método | En |
---|---|
Read | Lea el primer nodo y avance por la secuencia de nodo en nodo. Estas llamadas normalmente se realizan dentro de un while bucle.Use la NodeType propiedad para obtener el tipo (por ejemplo, atributo, comentario, elemento, etc.) del nodo actual. |
Skip | Omita los hijos del nodo actual y pase al siguiente nodo. |
MoveToContent y MoveToContentAsync | Omita los nodos que no son de contenido y pase al siguiente nodo de contenido o al final del archivo. Los nodos que no son de contenido incluyen ProcessingInstruction, DocumentType, Comment, Whitespacey SignificantWhitespace. Los nodos de contenido incluyen texto de espacio no en blanco, CDATA, EntityReference y EndEntity. |
ReadSubtree | Lea un elemento y todos sus elementos secundarios y devuelva una nueva instancia de XmlReader establecida en ReadState.Initial. Este método es útil para crear límites alrededor de elementos XML; Por ejemplo, si desea pasar datos a otro componente para su procesamiento y desea limitar la cantidad de datos a los que puede acceder el componente. |
Consulte la XmlReader.Read página de referencia para ver un ejemplo de cómo navegar por una secuencia de texto, un nodo a la vez, y cómo mostrar el tipo de cada nodo.
En las secciones siguientes se describe cómo leer tipos específicos de datos, como elementos, atributos y datos con tipo.
Leer elementos XML
En la tabla siguiente se enumeran los métodos y propiedades que proporciona la XmlReader clase para procesar elementos. Después de colocar el XmlReader en un elemento, las propiedades del nodo, como Name, reflejan los valores de ese elemento. Además de los miembros descritos a continuación, cualquiera de los métodos y propiedades generales de la XmlReader clase también se puede usar para procesar elementos. Por ejemplo, puede usar el ReadInnerXml método para leer el contenido de un elemento.
Nota:
Consulte la sección 3.1 de la Recomendación W3C XML 1.0 para las definiciones de etiquetas de inicio, etiquetas finales y etiquetas de elemento vacías.
Usar este miembro de XmlReader | En |
---|---|
método IsStartElement | Compruebe si el nodo actual es una etiqueta de inicio o una etiqueta de elemento vacía. |
método ReadStartElement | Compruebe que el nodo actual es un elemento y avance el lector al siguiente nodo (llamadas IsStartElement seguidas de Read). |
método ReadEndElement | Compruebe que el nodo actual es una etiqueta final y avance el lector al siguiente nodo. |
método ReadElementString | Lee un elemento de solo texto. |
método ReadToDescendant | Avance el lector XML al siguiente elemento descendiente (secundario) que tiene el nombre especificado. |
método ReadToNextSibling | Avance el lector XML al siguiente elemento relacionado que tiene el nombre especificado. |
Propiedad IsEmptyElement | Compruebe si el elemento actual tiene una etiqueta de elemento final. Por ejemplo: - <item num="123"/> (IsEmptyElement es true .)- <item num="123"> </item> (IsEmptyElement es false , aunque el contenido del elemento está vacío). |
Para obtener un ejemplo de lectura del contenido de texto de los elementos, vea el ReadString método . En el ejemplo siguiente se procesan los elementos mediante un while
bucle .
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
Leer atributos XML
Los atributos XML se encuentran con más frecuencia en los elementos, pero también se permiten en los nodos de declaración XML y tipo de documento.
Cuando se coloca en un nodo de elemento, el MoveToAttribute método le permite recorrer la lista de atributos del elemento. Tenga en cuenta que después de llamar a MoveToAttribute, las propiedades del nodo como Name, NamespaceURI y Prefix reflejan las propiedades de ese atributo, no las propiedades del elemento al que pertenece el atributo.
La XmlReader clase proporciona estos métodos y propiedades para leer y procesar atributos en elementos.
Usar este miembro de XmlReader | En |
---|---|
Propiedad HasAttributes | Compruebe si el nodo actual tiene atributos. |
Propiedad AttributeCount | Obtenga el número de atributos en el elemento actual. |
método MoveToFirstAttribute | Vaya al primer atributo de un elemento. |
método MoveToNextAttribute | Vaya al siguiente atributo de un elemento. |
método MoveToAttribute | Vaya a un atributo especificado. |
Método GetAttribute o propiedad Item[] | Obtiene el valor de un atributo especificado. |
Propiedad IsDefault | Compruebe si el nodo actual es un atributo que se generó a partir del valor predeterminado definido en el DTD o el esquema. |
método MoveToElement | Vaya al elemento que posee el atributo actual. Use este método para volver a un elemento después de navegar por sus atributos. |
método ReadAttributeValue | Parsee el valor del atributo en uno o varios nodos Text , EntityReference , o EndEntity . |
Cualquiera de los métodos y propiedades generales XmlReader también se puede usar para procesar atributos. Por ejemplo, después de que XmlReader se posicione en un atributo, las propiedades Name y Value reflejan los valores del atributo. También puede usar cualquiera de los métodos de contenido Read
para obtener el valor del atributo.
En este ejemplo se usa la AttributeCount propiedad para navegar por todos los atributos de un elemento.
// 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
En este ejemplo se usa el MoveToNextAttribute método en un while
bucle para navegar por los atributos.
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
Lectura de atributos en nodos de declaración XML
Cuando el lector XML se coloca en un nodo de declaración XML, la Value propiedad devuelve la información de versión, independiente y codificación como una sola cadena. Los objetos XmlReader creados por el método Create, la clase XmlTextReader y la clase XmlValidatingReader exponen los elementos de versión, independiente y codificación como atributos.
Lectura de atributos en nodos de tipo de documento
Cuando el lector XML se coloca en un nodo de tipo de documento, se pueden usar el método GetAttribute y la propiedad Item[] para devolver los valores de los literales SYSTEM y PUBLIC. Por ejemplo, llamar a reader.GetAttribute("PUBLIC")
devuelve el valor PUBLIC.
Lectura de atributos en nodos de instrucción de procesamiento
Cuando el XmlReader está posicionado en un nodo de instrucción de procesamiento, la propiedad Value devuelve todo el contenido de texto. Los elementos del nodo de instrucción de procesamiento no se tratan como atributos. No se pueden leer con el método GetAttribute o MoveToAttribute.
Leer contenido XML
La clase XmlReader incluye los siguientes miembros que leen contenido de un archivo XML y devuelven el contenido como valores de cadena. (Para devolver tipos CLR, consulte Conversión a tipos CLR).
Usar este miembro de XmlReader | En |
---|---|
Propiedad Value | Obtenga el contenido de texto del nodo actual. El valor devuelto depende del tipo de nodo; consulte la Value página de referencia para obtener más información. |
método ReadString | Obtiene el contenido de un elemento o nodo de texto como una cadena. Este método se detiene en el procesamiento de instrucciones y comentarios. Para obtener más información sobre cómo este método controla tipos de nodo específicos, consulte la ReadString página de referencia. |
métodos ReadInnerXml y ReadInnerXmlAsync | Obtenga todo el contenido del nodo actual, incluido el marcado, pero sin incluir etiquetas de inicio y finalización. Por ejemplo, para:<node>this<child id="123"/></node> ReadInnerXml devuelve lo siguiente: this<child id="123"/> |
métodos ReadOuterXml y ReadOuterXmlAsync | Obtenga todo el contenido del nodo actual y sus elementos secundarios, incluidas las etiquetas de marcado y inicio y finalización. Por ejemplo, para:<node>this<child id="123"/></node> ReadOuterXml devuelve lo siguiente: <node>this<child id="123"/></node> |
Conversión a tipos CLR
Puede usar los miembros de la XmlReader clase (enumerados en la tabla siguiente) para leer datos XML y devolver valores como tipos de Common Language Runtime (CLR) en lugar de cadenas. Estos miembros le permiten obtener valores en la representación más adecuada para la tarea de codificación sin tener que analizar ni convertir manualmente valores de cadena.
Los métodos ReadElementContentAs solo se pueden llamar en tipos de nodo de elemento. Estos métodos no se pueden utilizar en elementos que contienen elementos segundarios o incluyen contenido mixto. Cuando se llama, el XmlReader objeto lee la etiqueta de inicio, lee el contenido del elemento y, a continuación, se mueve más allá de la etiqueta de elemento final. Las instrucciones de procesamiento y los comentarios se omiten y las entidades se expanden.
Los métodos ReadContentAs leen el contenido de texto en la posición del lector actual y, si los datos XML no tienen ninguna información de esquema o tipo de datos asociada, convierta el contenido de texto en el tipo de valor devuelto solicitado. El texto, el espacio en blanco, los espacios en blanco significativos y las secciones CDATA se concatenan. Los comentarios y las instrucciones de procesamiento se omiten y las referencias de entidad se resuelven automáticamente.
La XmlReader clase usa las reglas definidas por la recomendación esquema XML W3C Parte 2: Tipos de datos .
Use este XmlReader método | Para devolver este tipo CLR |
---|---|
ReadContentAsBoolean y ReadElementContentAsBoolean | Boolean |
ReadContentAsDateTime y ReadElementContentAsDateTime | DateTime |
ReadContentAsDouble y ReadElementContentAsDouble | Double |
ReadContentAsLong y ReadElementContentAsLong | Int64 |
ReadContentAsInt y ReadElementContentAsInt | Int32 |
ReadContentAsString y ReadElementContentAsString | String |
ReadContentAs y ReadElementContentAs | El tipo que especifique con el returnType parámetro |
ReadContentAsObject y ReadElementContentAsObject | Tipo más adecuado, tal como se especifica en la XmlReader.ValueType propiedad . Consulte Compatibilidad de tipos en las clases System.Xml para obtener información sobre la asignación. |
Si un elemento no se puede convertir fácilmente a un tipo CLR debido a su formato, puede usar una asignación de esquema para garantizar una conversión correcta. En el ejemplo siguiente se usa un archivo .xsd para convertir el hire-date
elemento en el xs:date
tipo y, a continuación, se usa el ReadElementContentAsDateTime método para devolver el elemento como un DateTime objeto .
Input (hireDate.xml):
<employee xmlns="urn:empl-hire">
<ID>12365</ID>
<hire-date>2003-01-08</hire-date>
<title>Accountant</title>
</employee>
Esquema (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>
Código:
// 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
Salida:
Six Month Review Date: 7/8/2003 12:00:00 AM
Programación asincrónica
La mayoría de los XmlReader métodos tienen homólogos asincrónicos que tienen "Async" al final de sus nombres de método. Por ejemplo, el equivalente asincrónico de ReadContentAsObject es ReadContentAsObjectAsync.
Los métodos siguientes se pueden usar con llamadas de método asincrónicas:
- GetAttribute
- MoveToAttribute
- MoveToFirstAttribute
- MoveToNextAttribute
- MoveToElement
- ReadAttributeValue
- ReadSubtree
- ResolveEntity
En las secciones siguientes se describe el uso asincrónico de los métodos que no tienen homólogos asincrónicos.
Método 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
Método 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
Método ReadToNextSibling
public static async Task<bool> ReadToNextSiblingAsync(this XmlReader reader, string localName, string namespaceURI)
{
if (localName == null || localName.Length == 0)
{
throw new ArgumentException("localName is empty or null");
}
if (namespaceURI == null)
{
throw new ArgumentNullException("namespaceURI");
}
// atomize local name and namespace
localName = reader.NameTable.Add(localName);
namespaceURI = reader.NameTable.Add(namespaceURI);
// find the next sibling
XmlNodeType nt;
do
{
await reader.SkipAsync();
if (reader.ReadState != ReadState.Interactive)
break;
nt = reader.NodeType;
if (nt == XmlNodeType.Element &&
((object)localName == (object)reader.LocalName) &&
((object)namespaceURI ==(object)reader.NamespaceURI))
{
return true;
}
} while (nt != XmlNodeType.EndElement && !reader.EOF);
return false;
}
<Extension()>
Public Async Function ReadToNextSiblingAsync(reader As XmlReader, localName As String, namespaceURI As String) As Task(Of Boolean)
If (localName = Nothing Or localName.Length = 0) Then
Throw New ArgumentException("localName is empty or null")
End If
If (namespaceURI = Nothing) Then
Throw New ArgumentNullException("namespaceURI")
End If
' atomize local name and namespace
localName = reader.NameTable.Add(localName)
namespaceURI = reader.NameTable.Add(namespaceURI)
' find the next sibling
Dim nt As XmlNodeType
Do
Await reader.SkipAsync()
If (reader.ReadState <> ReadState.Interactive) Then
Exit Do
End If
nt = reader.NodeType
If ((nt = XmlNodeType.Element) And
((CObj(localName) = CObj(reader.LocalName))) And
(CObj(namespaceURI) = CObj(reader.NamespaceURI))) Then
Return True
End If
Loop While (nt <> XmlNodeType.EndElement And (Not reader.EOF))
Return False
End Function
ReadToFollowing (método)
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
Método 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
Consideraciones de seguridad
Tenga en cuenta lo siguiente al trabajar con la XmlReader clase :
Las excepciones producidas por el XmlReader pueden revelar información sobre la ruta de acceso que quizá no quiera que aparezca en su aplicación. La aplicación debe detectar excepciones y procesarlas correctamente.
No habilite el procesamiento de DTD si le preocupan los problemas de denegación de servicio o si está tratando con orígenes que no son de confianza. El procesamiento de DTD está deshabilitado de forma predeterminada para XmlReader los objetos creados por el Create método .
Si tiene habilitado el procesamiento de DTD, puede usar el XmlSecureResolver para restringir recursos a los que XmlReader puede acceder. También puede diseñar su aplicación para que el procesamiento XML esté restringido en memoria y tiempo. Por ejemplo, puede configurar límites de tiempo de espera en la aplicación de ASP.NET.
Los datos XML pueden incluir referencias a recursos externos, como un archivo de esquema. De forma predeterminada, los recursos externos se resuelven mediante un XmlUrlResolver objeto sin credenciales de usuario. Puede proteger esto aún más si realiza una de las siguientes acciones:
Restrinja los recursos a los que XmlReader puede acceder configurando el valor de la propiedad XmlReaderSettings.XmlResolver en un objeto XmlSecureResolver.
No permita que XmlReader abra ningún recurso externo al establecer la propiedad XmlReaderSettings.XmlResolver en
null
.
Las ProcessInlineSchema marcas de validación y ProcessSchemaLocation de un XmlReaderSettings objeto no se establecen de forma predeterminada. Esto ayuda a proteger XmlReader contra ataques basados en esquemas cuando procesa datos XML de una fuente no confiable. Cuando se establecen estas marcas, se utiliza el XmlResolver del objeto XmlReaderSettings para resolver las ubicaciones de esquemas que se encuentra en el documento de la instancia de XmlReader. Si la propiedad XmlResolver se establece en
null
, las ubicaciones de esquema no se resuelven incluso si las marcas de validación ProcessInlineSchema y ProcessSchemaLocation están establecidas.Los esquemas agregados durante la validación agregan nuevos tipos y pueden cambiar el resultado de validación del documento que se está validando. Como resultado, los esquemas externos solo deben resolverse desde orígenes de confianza.
Recomendamos deshabilitar la ProcessIdentityConstraints marca al validar documentos XML grandes y no confiables en escenarios de alta disponibilidad, contra un esquema que tenga restricciones de identidad sobre una gran parte del documento. Esta marca está habilitada de forma predeterminada.
Los datos XML pueden contener un gran número de atributos, declaraciones de espacio de nombres, elementos anidados, etc. que requieren una cantidad considerable de tiempo para procesarse. Para limitar el tamaño de la entrada que se envía a XmlReader, puede:
Limite el tamaño del documento estableciendo la MaxCharactersInDocument propiedad .
Limite el número de caracteres resultantes de expandir entidades estableciendo la MaxCharactersFromEntities propiedad .
Cree una implementación personalizada
IStream
para el XmlReader.
El ReadValueChunk método se puede usar para controlar grandes flujos de datos. Este método lee un pequeño número de caracteres a la vez en lugar de asignar una sola cadena para todo el valor.
Al leer un documento XML con un gran número de nombres locales únicos, espacios de nombres o prefijos, puede producirse un problema. Si está usando una clase que deriva de XmlReader y llama a las propiedades LocalName, Prefix o NamespaceURI para cada elemento, la cadena devuelta se agrega a un NameTable. La colección contenida por NameTable nunca disminuye de tamaño, creando una pérdida de memoria virtual de los identificadores de cadena. Una mitigación para esto es derivar de la NameTable clase y aplicar una cuota de tamaño máximo. (No hay manera de evitar el uso de un NameTable, o de cambiar el NameTable cuando está lleno). Otra mitigación consiste en evitar el uso de las propiedades mencionadas y, en su lugar, usar el MoveToAttribute método con el IsStartElement método siempre que sea posible; esos métodos no devuelven cadenas y, por tanto, evitan el problema de sobrellenar la NameTable colección.
XmlReaderSettings los objetos pueden contener información confidencial, como las credenciales de usuario. Un componente que no es de confianza podría usar el XmlReaderSettings objeto y sus credenciales de usuario para crear XmlReader objetos para leer datos. Tenga cuidado al almacenar en caché XmlReaderSettings objetos o al pasar el XmlReaderSettings objeto de un componente a otro.
No acepte componentes auxiliares, como NameTable, XmlNamespaceManagery XmlResolver objetos, de un origen que no sea de confianza.