Pergunta

Em um pergunta anterior eu mencionei algum trabalho com um 3º DLL partido cuja interface utiliza uma série de entradas XML que são definidos usando DTDs. Tudo tem corrido bem até agora, mas eu ainda tenho esta questão lancinante com resolução de Declaração Tipo de Documento nos valores de entrada gerados.

O que eu não consigo entender é que o fator decisivo é a determinar para onde olhar para o arquivo DTD referenciado. Se eu tiver uma declaração parecida com esta:

<!DOCTYPE ElementName SYSTEM "ElementName.dtd">

Meu pensamento inicial era de que a actual caminho de execução do aplicativo é o lugar onde um analisador iria olhar para o DTD. No entanto, quando tento usar um controle XML em ASP.Net, o erro que recebo defletores me ...

Não foi possível encontrar o arquivo c': \ Program Files \ Microsoft Visual Estúdio 9.0 \ Common7 \ IDE \ ElementName.dtd '

Por que é procurando o DTD lá?

Há algum XML gurus lá fora que possa me ajudar em um presente. Eu realmente não tenho nenhum controle sobre o XML que é retornado a partir desta DLL então o que é que eu vou fazer. Existe uma maneira de "registrar" um DTD com o sistema operacional? Como o GAC?

Foi útil?

Solução

Infelizmente a biblioteca que gerou o XML usado um URL relativo para o dtd em vez de um totalmente qualificado. Como tal XmlDocument do XmlControl está usando um href="http://msdn.microsoft.com/en-us/library/system.xml.xmlresolver.aspx" rel="nofollow noreferrer"> XmlResolver classe para converter o caminho relativo para um totalmente qualificado. Por padrão, ele usa um XmlUrlResolver (que é um XmlResolver concreto). Isto irá tentar mapear a localização da DTD para um local que pensa é em relação ao documento XML. é problema, onde está o XmlDocument? Provavelmente na memória que não é relativo a qualquer coisa ea XmlUrlResolver está usando a localização processo em vez que no seu caso é Visual Studio, que está localizado em 'c: \ Program Files \ Microsoft Visual Studio 9.0 \ Common7 \ IDE \ devenv.exe'.

Então, o que você pode fazer? Bem, eu suponho que você tem a caixa que você próprio XmlResolver que herda de XmlUrlResolver um substitui o método ResolveUri e faz algo apropriado. Tendo feito isso você terá que:

  1. Crie uma classe XmlReaderSettings e defina a propriedade XmlReolver para a classe recém-criada.
  2. Criar um XmlReader usando XmlReader.Create () passando em seu documento e as XmlSettings objeto.
  3. Criar um XmlDocument e chamada de carga passando o XmlReader e, finalmente.
  4. Defina a propriedade XmlDocument do seu XmlControl ao XmlDocument.

Francamente isso é tudo um pouco de dor, então se ele onde me que eu iria usar apenas String.Replace para remover a declaração DTD do documento antes de processá-lo em XML.

Se você está se sentindo realmente corajoso, você pode criar um resolvedor que herda diretamente do XmlResolver. Depois de ter feito isso você pode substituir o GetEntity método e, em seguida, você pode obter o documento DTD de onde quer que você gosta. Eu escrevi uma vez que dtds tenho de arquivos incorporados como arquivos de recursos, mas, infelizmente, eu não tenho o código mais: - (

Outras dicas

Se você realmente não se preocupam com validando cada documento contra sua DTD, você pode definir a propriedade XmlResolver como nulo no seu XmlTextReader (ou XmlDocument) para ignorar o DTD completamente.

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