2009-07-10 3 views
2

J'ai un certain nombre de documents XML plutôt volumineux et complexes que je dois parcourir. Un xmlns est défini en haut du document, mais l'URL vers laquelle il pointe n'est plus disponible.Analyser un document XML lorsque l'espace de noms n'est plus disponible

Quelle est la meilleure façon d'analyser le fichier pour obtenir les données importantes en utilisant C#?

J'ai essayé de le charger dans un ensemble de données mais recevrait occasionnellement les erreurs: La table (point de terminaison) ne peut pas être la table enfant à elle-même dans les relations imbriquées. ou Impossible d'ajouter une colonne SimpleContent à une table contenant des colonnes d'élément ou des relations imbriquées. XPath était mon prochain port d'escale, mais j'ai eu des problèmes à cause du manque d'espace de noms.

Je suppose que cela limite sérieusement mes options, mais est-ce que quelqu'un a des suggestions?

Snippet du document XML:

<?xml version="1.0" encoding="UTF-8"?> 
<cdr:cdr_set xmlns:cdr="http://www.naturalconvergence.com/schema/cdr/v3/cdr"> 

<!-- Copyright (c) 2001-2009, all rights reserved --> 

<cdr:cdr xmlns:cdr="http://www.naturalconvergence.com/schema/cdr/v3/cdr"> 
    <cdr:call_id>2040-1247062136726-5485131</cdr:call_id> 
    <cdr:cdr_id>1</cdr:cdr_id> 
    <cdr:status>Normal</cdr:status> 
    <cdr:responsibility> 
    <cdr:tenant id="17"> 
     <cdr:name>SpiriTel plc</cdr:name> 
    </cdr:tenant> 
    <cdr:site id="45"> 
     <cdr:name>KWS</cdr:name> 
     <cdr:time_zone>GB</cdr:time_zone> 
    </cdr:site> 
    </cdr:responsibility> 
    <cdr:originator type="sipGateway"> 
    <cdr:sipGateway id="3"> 
     <cdr:name>Audiocodes-91</cdr:name> 
    </cdr:sipGateway> 
    </cdr:originator> 
    <cdr:terminator type="group"> 
    <cdr:group> 
     <cdr:tenant id="17"> 
     <cdr:name>SpiriTel plc</cdr:name> 
     </cdr:tenant> 
     <cdr:type>Broadcast</cdr:type> 
     <cdr:extension>6024</cdr:extension> 
     <cdr:name>OLD PMS DDIS DO NOT USE</cdr:name> 
    </cdr:group> 
    </cdr:terminator> 
    <cdr:initiation>Dialed</cdr:initiation> 
    <cdr:calling_number>02087893850</cdr:calling_number> 
    <cdr:dialed_number>01942760142</cdr:dialed_number> 
    <cdr:target>6024</cdr:target> 
    <cdr:direction>Inbound</cdr:direction> 
    <cdr:disposition>No Answer</cdr:disposition> 
    <cdr:timezone>GB</cdr:timezone> 
    <cdr:origination_timestamp>2009-07-08T15:08:56.727+01:00</cdr:origination_timestamp> 
    <cdr:release_timestamp>2009-07-08T15:09:26.493+01:00</cdr:release_timestamp> 
    <cdr:release_cause>Normal Clearing</cdr:release_cause> 
    <cdr:call_duration>PT29S</cdr:call_duration> 
    <cdr:redirected>false</cdr:redirected> 
    <cdr:conference>false</cdr:conference> 
    <cdr:transferred>false</cdr:transferred> 
    <cdr:estimated>false</cdr:estimated> 
    <cdr:interim>false</cdr:interim> 
    <cdr:segments> 
    <cdr:segment> 
     <cdr:originationTimestamp>2009-07-08T15:08:56.727+01:00</cdr:originationTimestamp> 
     <cdr:initiation>Dialed</cdr:initiation> 
     <cdr:call_id>2040-1247062136726-5485131</cdr:call_id> 
     <cdr:originator type="sipGateway"> 
     <cdr:sipGateway id="3"> 
      <cdr:name>Audiocodes-91</cdr:name> 
     </cdr:sipGateway> 
     </cdr:originator> 
     <cdr:termination_attempt> 
     <cdr:termination_timestamp>2009-07-08T15:08:56.728+01:00</cdr:termination_timestamp> 
     <cdr:terminator type="group"> 
      <cdr:group> 
      <cdr:tenant id="17"> 
       <cdr:name>SpiriTel plc</cdr:name> 
      </cdr:tenant> 
      <cdr:type>Broadcast</cdr:type> 
      <cdr:extension>6024</cdr:extension> 
      <cdr:name>OLD PMS DDIS DO NOT USE</cdr:name> 
      </cdr:group> 
     </cdr:terminator> 
     <cdr:provided_address>01942760142</cdr:provided_address> 
     <cdr:direction>Inbound</cdr:direction> 
     <cdr:disposition>No Answer</cdr:disposition> 
     </cdr:termination_attempt> 
    </cdr:segment> 
    </cdr:segments> 
</cdr:cdr> 

... 

</cdr:cdr_set> 

Chaque entrée est essentiellement le même, mais il y a parfois des différences telles que certains champs peuvent manquer, si elles ne sont pas nécessaires.

+0

(exemple mis à jour re comment) –

Répondre

5

Ces valeurs dans un fichier xml sont identificateurs, pas locators. À moins que vous ne prévoyiez de télécharger un schéma, il n'est pas nécessaire du tout et peut être "flibble" si nécessaire. Je m'attends à ce que la meilleure chose serait de simplement le charger dans XmlDocument/XDocument et essayer d'accéder aux données.

Par exemple:

XmlDocument doc = new XmlDocument(); 
doc.Load("cdr.xml"); 
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable); 
ns.AddNamespace("cdr", "http://www.naturalconvergence.com/schema/cdr/v3/cdr"); 
XmlElement el = (XmlElement)doc.SelectSingleNode(
    "cdr:cdr_set/cdr:cdr/cdr:originator", ns); 
Console.WriteLine(el.GetAttribute("type")); 

ou boucle sur les cdr éléments:

foreach (XmlElement cdr in doc.SelectNodes("/cdr:cdr_set/cdr:cdr", ns)) 
    { 
     Console.WriteLine(cdr.SelectSingleNode("cdr:call_id", ns).InnerText); 
    } 

Notez que les alias utilisés dans le document sont en grande partie sans rapport avec les alias utilisés dans le XmlNamespaceManager, donc vous besoin de le re-déclarer. J'aurais pu utiliser aussi facilement mon x comme alias dans le C#.


Bien sûr, si vous préférez travailler avec un modèle d'objet; exécuter par xsd (où cdr.xml est votre fichier par exemple):

xsd cdr.xml 
xsd cdr.xsd /classes 

Maintenant, vous pouvez le charger avec XmlSerializer.

+0

J'ai essayé ceci et la ligne XmlNodeList nœuds = root.SelectNodes ("/ cdr: cdr"); génère l'exception "Namespace Manager ou XsltContext nécessaire Cette requête a un préfixe, une variable ou une fonction définie par l'utilisateur." –

+0

(répondu à la question) –

+0

Code sippet travaillé, je n'ai aucune idée de ce que vous avez fait différemment, je suppose que ma requête xpath était incorrecte. Thnak vous! –

1

de le charger dans un Xdocument et d'utiliser linq2XML? ... même si vous pourriez avoir la même erreur.

Je ne sais pas quelles données vous voulez, il est donc difficile de suggérer une requête. Je préfère personnellement l'utilisation de XDocument à xmlDocument dans la plupart des cas. Le seul problème avec la génération automatique d'un XSD est qu'il peut mal tourner vos types de données si vous n'utilisez pas un bloc de données de bonne taille.

+0

En effet, quand je l'ai essayé, xsd a fait un travail assez médiocre que 'XmlSerializer' a effectivement refusé de charger ... –

+0

Je ressens votre douleur;) Je finis généralement par réécrire xsd généré automatiquement ... mais au moins c'est une belle point de départ. –

Questions connexes