saber nodo leer existe especifico crear atributos c# xml .net-2.0 xsd xml-validation

nodo - leer xml c# xmlreader



Validar nodos xml, no todo el documento (6)

Estoy trabajando con algunos ''fragmentos'' xml que forman elementos en el xml. Tengo el esquema pero no puedo validar estos archivos porque no son documentos xml completos. Estos fragmentos están envueltos con los elementos principales necesarios para formar xml válido cuando se usan en otras herramientas, por lo que no tengo muchas opciones para convertirlos en xml válidos o cambiar el esquema.

¿Es posible validar un elemento, en lugar de todo el documento? Si no, ¿qué soluciones alternativas podrían sugerirse?

Estoy trabajando en C # con el framework .NET 2.0.


Hay un método XmlDocument.Validate que toma un XmlNode como argumento y valida solo este nodo. Eso puede ser lo que estás buscando ...


Puede usar un alias de espacio de nombre especial para asignar los elementos que desea validar y luego solo agregar el esquema para ese alias de espacio de nombres pero no para otros. De esta forma, solo aquellos elementos con su prefijo especial de espacio de nombres serán validados.


No parece posible hacer lo que aspiro a hacer. Mi trabajo actual es crear un documento xml de plantilla en blanco. Luego reemplace el elemento deseado con mi fragmento. A partir de ahí, creo que el método Validate sería viable. Pero crear esta plantilla dinámicamente parece ser otra tarea desalentadora por derecho propio. No parece haber una manera fácil de crear un documento ''esqueleto''.


Ok, aquí hay otro enfoque:

Podría transformar su archivo de esquema utilizando una transformación XSLT en un nuevo esquema que tenga sus elementos de fragmento como raíz. Digamos que su esquema original sería

<xs:schema id="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="RootElement"> <xs:complexType> <xs:sequence> <xs:element name="NestedElement"> <xs:complexType> <xs:attribute name="Name" type="xs:string" use="required"/> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>

Tiene fragmentos de tipo NestedElement que desea validar:

<NestedElement Name1="Name1" />

Entonces podrías usar una plantilla XSLT como

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="xs:element[@name=''NestedElement'']" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:schema id="MySchema"> <xsl:copy-of select="."/> </xs:schema> </xsl:template> </xsl:stylesheet>

Para crear un nuevo esquema que tenga NestedElement como raíz. El esquema resultante se vería como

<xs:schema id="MySchema" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="NestedElement"> <xs:complexType> <xs:attribute name="Name" type="xs:string" use="required" /> </xs:complexType> </xs:element> </xs:schema>

A continuación, puede validar un documento de fragmento contra este nuevo esquema utilizando un código como

XmlSchema schema; using (MemoryStream stream = new MemoryStream()) using (FileStream fs = new FileStream("MySchema.xsd", FileMode.Open)) using(XmlReader reader = XmlReader.Create(fs)) { XslCompiledTransform transform = new XslCompiledTransform(); transform.Load("SchemaTransform.xslt"); transform.Transform(reader, null, stream); stream.Seek(0, SeekOrigin.Begin); schema = XmlSchema.Read(stream, null); } XmlDocument doc = new XmlDocument(); doc.Schemas.Add(schema); doc.Load("rootelement.xml"); doc.Validate(ValidationHandler);

MySchema.xsd es el esquema original, SchemaTransform.xslt es la transformación (como se muestra arriba), rootelement.xml es un documento XML que contiene un solo nodo de fragmento.


Tuve un problema similar en el que solo pude validar partes de mi documento XML. Se me ocurrió este método aquí:

private void ValidateSubnode(XmlNode node, XmlSchema schema) { XmlTextReader reader = new XmlTextReader(node.OuterXml, XmlNodeType.Element, null); XmlReaderSettings settings = new XmlReaderSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; settings.Schemas.Add(schema); settings.ValidationType = ValidationType.Schema; settings.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler); using (XmlReader validationReader = XmlReader.Create(reader, settings)) { while (validationReader.Read()) { } } } private void XSDValidationEventHandler(object sender, ValidationEventArgs args) { errors.AppendFormat("XSD - Severity {0} - {1}", args.Severity.ToString(), args.Message); }

Básicamente, le paso un XmlNode (que selecciono de todo el XmlDocument por medio de .SelectSingleNode), y un esquema XML que cargo desde un recurso incrustado XSD dentro de mi aplicación. Cualquier error de validación que pueda ocurrir se rellena en un generador de cadenas de "errores", que luego leo al final, para ver si se registraron errores o no.

Funciona para mí, tu kilometraje puede variar :-)


Yo tuve el mismo problema. Incluso me preguntaron por la solución. He encontrado una solución.

El problema es que solo los elementos raíz se pueden validar. Entonces ... edito el esquema EN MEMORIA y agrego el elemento / tipo para validar a la raíz

public static void AddElementToSchema(XmlSchema xmlSchema, string elementName, string elementType, string xmlNamespace) { XmlSchemaElement testNode = new XmlSchemaElement(); testNode.Name = elementName; testNode.Namespaces.Add("", xmlNamespace); testNode.SchemaTypeName = new XmlQualifiedName(elementType, xmlNamespace); xmlSchema.Items.Add(testNode); xmlSchema.Compile(XMLValidationEventHandler); }

Solo un par de líneas y no debe modificar ni agregar ningún archivo XSD :) Con este simple cambio en su esquema en memoria, puede validar el fragmento con el mismo código que usa para validar un documento completo. Solo asegúrese de que el elemento raíz del fragmento para validar incluya el espacio de nombres. :)