Pergunta

Eu estou trabalhando com alguns XML 'trechos' que elementos do formulário abaixo a xml. Eu tenho o esquema, mas não posso validar esses arquivos porque eles não são documentos completos xml. Esses trechos são envolvidos com os elementos pai necessárias para formar um XML válido quando eles são usados ??em outras ferramentas para que eu não tenho muita opção em fazê-los em XML válido ou na mudança do esquema.

É possível validar um elemento, em vez de todo o documento? Se não, quais soluções podem ser sugeridas?

Eu estou trabalhando em C # com o .NET Framework 2.0.

Foi útil?

Solução

Eu tive um problema semelhante onde eu só poderia validar partes do meu documento XML. Eu vim com esse método aqui:

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);
}

Basicamente, eu passá-lo um XmlNode (que eu selecionar a partir de todo o XmlDocument por meio de .SelectSingleNode), e um esquema XML que eu carga de um XSD recurso incorporado dentro do meu aplicativo. Quaisquer erros de validação que podem ocorrer estão sendo enfiados em um "erros" construtor de corda, que eu então lida no final, para ver se houve algum erro registrado, ou não.

funciona para mim - sua milhagem pode variar: -)

Outras dicas

Existe um método XmlDocument.Validate que leva um XmlNode como argumento uma valida apenas neste nó. Isso pode ser o que você está procurando ...

Ok, aqui está uma outra abordagem:

Você poderia transformar o arquivo de esquema utilizando uma transformação XSLT em um novo esquema que tem seus elementos trecho como raiz. Digamos que o seu esquema original seria

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

Você tem trechos de tipo NestedElement que você deseja validar:

<NestedElement Name1="Name1" />

Em seguida, você poderia usar um modelo 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 criar um novo esquema que tem NestedElement como root. O esquema resultante seria semelhante

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

Você pode então validar um documento trecho contra este novo esquema usando um 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 é o esquema original, SchemaTransform.xslt é a transformação (tal como mostrado acima), rootelement.xml é um documento XML que contém um único nó fragmento.

Você pode usar um apelido especial namespace de destinar os elementos que você deseja validar e só então adicionar esquema para esse alias namespace, mas não para outros. Desta forma apenas os elementos com o seu prefixo especial namespace vai ter validado.

Não me parece possível fazer o que eu aspiro a fazer. Meu trabalho atual em torno é criar um modelo de documento xml em branco. Em seguida, substitua o elemento desejado com meu trecho. De lá, acredito que o método Validar, então, seria viável. Mas para criar esse modelo de forma dinâmica parece ser outra tarefa difícil em seu próprio direito. Não parece haver nenhuma maneira fácil de criar um 'esqueleto' do documento.

Eu tive o mesmo problema. Mesmo perguntou aqui para solução. Eu encontrei uma solução alternativa.

O problema é que apenas os elementos de raiz pode ser validado. Então ... editar eu o esquema na memória e adicionar o elemento / tipo para validar a raiz

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);
}

Apenas um par de linhas e você não deve modificar ou adicionar quaisquer arquivos XSD :) Com esta simples alteração no seu esquema de memória, você pode validar o fragmento com o mesmo código que você usa para validar um documento completo. Apenas certifique-se que o elemento raiz do fragmento para validar inclui o namespace. :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top