Pergunta

Quero testar (verdadeiro ou falso) se um arquivo XML arbitrário corresponde a um determinado esquema.

Pelo que vale a pena, o esquema é a palavra esquema WordML de 2003, que a Microsoft define usando uma lista de cerca de 7 *.xsd arquivos.

Um desses arquivos também inclui o W3C xml.xsd Arquivo, incluindo a seguinte declaração:

<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"
    schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import>

Estou usando o código .NET como o seguinte para fazer a validação:

   public static void validate(string filename)
    {
       XmlReaderSettings settings = new XmlReaderSettings();
       settings.Schemas.Add(
           "http://schemas.microsoft.com/office/word/2003/wordml",
           //to get this file I downloaded "Office 2003: XML Reference Schemas", i.e. "Office2003XMLSchema.exe" 
           @"C:\Program Files\Microsoft Office 2003 Developer Resources\Microsoft Office 2003 XML Reference Schemas\WordprocessingML Schemas\wordnet.xsd"
           );
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler);
        XmlReader xmlReader = XmlReader.Create(filename, settings);
        while (xmlReader.Read()) { }
   }

Meu problema é que, se eu executar este código em uma máquina que não está conectada à Internet, então eu recebo um XmlSchemaValidationException erro no efeito que não consegue encontrar xml.xsd.

Para consertar isso, baixei uma cópia do XML.xsd e adicionei explicitamente usando o settings.Schemas.Add Método: A validação agora funciona corretamente quando a máquina não está conectada à Internet.

No entanto, quando a máquina está conectada à Internet, agora recebo um erro dizendo que The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared..

Então, aparentemente, eu preciso adicioná -lo explicitamente, ou não, dependendo se a máquina é capaz de baixá -la silenciosamente na Internet (ou mesmo talvez tenha sido capaz de baixá -lo e o cache em algum lugar).

Então, é "condenado se eu fizer e condenado se não". Preciso tentar de uma maneira, pegar a exceção e depois tentar de outra maneira? Ou existe uma solução mais elegante?

Foi útil?

Solução

Não podemos ver seu código, mas Em muitas implementações, isso é tratado redirecionando a solicitação do .xsd para a cópia local usando um resolvedor de catálogo. Há uma propriedade XmlReaderSettings.xmlResolver Isso pode ser usado para isso. Ver Xmlcatalog.net Para uma implementação licenciada por Apache que você pode usar.

Um efeito colateral disso é que você pode manter todos os esquemas armazenados em cache localmente. Isso é especialmente importante, pois o W3C bloqueará leituras excessivas no site e seu código aleatoriamente (ou pior, o código do seu cliente) começará a falhar.

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