2009-01-08 9 views
5

J'ai un document de modèle xml que j'ai besoin de charger dans un XmlDocument. par exempleXmlDocument et traitement de schéma lent

myXMLDocument.Load(myXMLFile); 

Cependant, cela est très lent car il se charge dans le dtd. J'ai essayé à la fois "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" et une copie locale de la DDT. Les deux prennent plus ou moins le même temps. Si je me contente de charger le dtd en définissant le résolveur sur null (par exemple), j'obtiens alors des erreurs telles que "Reference to undeclared entity 'nbsp'" si le document les contient.

J'ai besoin d'utiliser un XmlDocument car j'ai besoin de manipuler le DOM avant de sortir le document. Comment puis-je contourner ces problèmes?

Répondre

2

Vous pouvez éviter la DTD si vous retournez un flux de mémoire vide:

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(); 
    } 
} 
+0

Cela ne me semble pas une solution : si le XML contient des entités définies dans la DTD référencée, il échouera à analyser – MiMo

0

Regardez le fichier DTD, il existe d'autres références en ligne aux fichiers .mod, peut-être que cela ralentit le processus. Vous pouvez également essayer de commenter certains d'entre eux, certains d'entre eux, mais pas tous sont marqués comme "requis" dans les commentaires.

+0

j'ai enlevé tous sauf ceux nécessaires, mais il n'a pas la vitesse de manière significative vers le haut .. :(Je – Sprintstar

-1

Avez-vous essayé de créer un résolveur fictif qui renvoie null pour un chemin dtd et le passant dans la commande load? Quelque chose comme:

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"); 
+1

essayé juste cela, mais il a causé xmlDocument.Load pour lancer une exception «Référence de l'objet non défini à une instance d'un objet» .. :( – Sprintstar

0

C'est lent car il est téléchargé à partir du réseau. Pour résoudre ce problème, procédez comme suit:

  • Télécharger le * .mod et fichiers * .ent référencé par la DTD (votre instance XmlResolver vous dira les noms des URIs qui sont recherchée)
  • Ajouter ces fichiers à votre projet en tant que fichiers de ressources
  • Définir une sous-classe de XmlResolver, dont la méthode GetEntity() retourne un flux créé à partir du fichier de ressources locales
3

réponse de ChrisW semble intéressant, mais je mis en place un résolveur de mise en cache de cette lien: http://msdn.microsoft.com/en-us/library/bb669135.aspx

Cela a augmenté la vitesse d'environ 11.5s à 160ms, ce qui est probablement assez bon pour l'instant. Si ce n'est pas encore assez rapide, je vais implémenter la solution de ChrisW. :)

+0

Merci d'avoir posté cela. – ChrisW

+0

+1, a travaillé pour moi – MiMo