XmlDocument e processamento de esquema lenta
-
05-07-2019 - |
Pergunta
Eu tenho um documento modelo de xml que eu preciso carregar em um XmlDocument. eg
myXMLDocument.Load(myXMLFile);
No entanto, este é muito lento, uma vez que carrega no DTD. Eu tentei tanto "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
e uma cópia local do DTD. Ambos levar mais ou menos ao mesmo tempo. Se eu virar de carregar o DTD, definindo o resolvedor nula (por exemplo), então eu recebo erros como "Reference to undeclared entity 'nbsp'"
se o documento contém estes.
Eu preciso usar um XmlDocument que eu preciso para manipular o DOM antes de emitir o documento. Como posso contornar esses problemas?
Solução
Você pode evitar o DTD se você retornar um fluxo de memória vazio:
private class DummyResolver : XmlResolver
{
public override System.Net.ICredentials Credentials
{
set
{
// Do nothing.
}
}
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
return new System.IO.MemoryStream();
}
}
Outras dicas
A resposta de ChrisW parece interessante, no entanto eu implementei um resolvedor cache a partir deste link: http://msdn.microsoft.com/en-us/library/bb669135.aspx
Isso aumentou a velocidade de 11.5s ao redor de 160ms, o que provavelmente é bom o suficiente para agora. Se o suficiente ainda não rápida vou impliment solução de ChrisW. :)
Olhe para o arquivo DTD, existem algumas referências mais on-line para arquivos .MOD, talvez estes retardar o processo. Você também pode tentar a comentar alguns deles, alguns deles, mas nem todos são marcados como "necessária" nos comentários.
É lento porque está a ser transferidos da rede. Para corrigir isso, faça o seguinte:
- Baixe o .mod * e * arquivos .ent referenciado pelo DTD (sua instância XmlResolver irá dizer-lhe os nomes dos URIs que estão sendo procurados)
- Adicionar esses arquivos para seu projeto como arquivos de recursos
- Definir uma subclasse de XmlResolver, cujo GetEntity () retorna um fluxo criado a partir do arquivo de recurso local
Você tentou criar um resolvedor manequim que retorna nulo para qualquer caminho DTD e passando isso para o comando de carregamento? Algo como:
class DummyResolver : XmlUrlResolver
{
public override Uri ResolveUri (Uri baseUri, String relativeUri)
{
return null;
}
}
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.XmlResolver = new DummyResolver();
xmlDocument.Load(@"whatever.xml");