Question

Je suis en train d'analyser certaines informations de l'API de géocodage de Google, mais je suis un peu de mal à obtenir efficacement les données sur le xml. lien Voir par exemple

Tout ce que je les soins devient de la short_name de address_component où le type est administrative_area_level_1 et la long_name de administrative_area_level_2 Cependant, avec mon programme de test ma requête XPath retourne aucun résultat pour les deux requêtes.

public static void Main(string[] args)
{
    using(WebClient webclient = new WebClient())
    {
        webclient.Proxy = null;
        string locationXml = webclient.DownloadString("http://maps.google.com/maps/api/geocode/xml?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false");
        using(var reader = new StringReader(locationXml))
        {
            var doc = new XPathDocument(reader);
            var nav = doc.CreateNavigator();
            Console.WriteLine(nav.SelectSingleNode("/GeocodeResponse/result/address_component[type=administrative_area_level_1]/short_name").InnerXml);
            Console.WriteLine(nav.SelectSingleNode("/GeocodeResponse/result/address_component[type=administrative_area_level_2]/long_name").InnerXml);

        }
    }
}

aide quelqu'un peut me trouver ce que je fais mal, ou de recommander une façon meilleure?

Était-ce utile?

La solution

Vous devez mettre la valeur du nœud que vous recherchez entre guillemets:

".../address_component[type='administrative_area_level_1']/short_name"
                            ↑                           ↑

Autres conseils

Je recommande vivement l'utilisation LINQ to XML au lieu de XPathNavigator. Il fait un jeu d'enfant XML interrogation, dans mon expérience. Dans ce cas, je ne sais pas exactement ce qui ne va pas ... mais je viendrai avec un LINQ à XML snippet à la place.

using System;
using System.Linq;
using System.Net;
using System.Xml.Linq;

class Test
{
    public static void Main(string[] args)
    {
        using(WebClient webclient = new WebClient())
        {
            webclient.Proxy = null;
            string locationXml = webclient.DownloadString
                ("http://maps.google.com/maps/api/geocode/xml?address=1600"
                 + "+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false");
            XElement root = XElement.Parse(locationXml);

            XElement result = root.Element("result");
            Console.WriteLine(result.Elements("address_component")
                                    .Where(x => (string) x.Element("type") ==
                                           "administrative_area_level_1")
                                    .Select(x => x.Element("short_name").Value)
                                    .First());
            Console.WriteLine(result.Elements("address_component")
                                    .Where(x => (string) x.Element("type") ==
                                           "administrative_area_level_2")
                                    .Select(x => x.Element("long_name").Value)
                                    .First());
        }
    }
}

Maintenant, ce plus de code 1 ... mais je trouve personnellement plus facile d'obtenir le droit de XPath, parce que le compilateur me aide plus.

EDIT: Je pense que ça vaut aller dans un peu plus en détail pourquoi je en général préfère code comme ceci sur l'utilisation XPath, même si elle est nettement plus longue

.

Lorsque vous utilisez XPath dans un programme C #, vous avez deux langues différentes - mais un seul est dans le contrôle (C #). XPath est reléguée au domaine des chaînes: Visual Studio ne donne pas une expression XPath aucune manipulation particulière; il n'a pas comprendre qu'il est censé être une expression XPath, donc il ne peut pas vous aider. Il est pas que Visual Studio ne connaît pas XPath; comme Dimitre souligne, il est parfaitement capable de repérer les erreurs si vous modifiez un fichier XSLT, mais pas un fichier C #.

Ceci est le cas chaque fois que vous avez un langage intégré dans une autre et l'outil est pas au courant. Des exemples courants sont les suivants:

  • SQL
  • Les expressions régulières
  • HTML
  • XPath

Lorsque le code est présenté sous forme de données dans une autre langue, la langue secondaire perd beaucoup de ses avantages d'outillage.

Alors que vous peut changement de contexte dans tous les sens, en tirant le XPath (ou SQL, ou des expressions régulières, etc.) dans leur propre outillage (éventuellement dans le même programme réel, mais dans un fichier séparé ou fenêtre) Je trouve cela rend plus difficile pour le code à lire à long terme. Si le code n'ont été jamais écrit et jamais lu par la suite, cela pourrait être bien -. Mais vous ne doivent être en mesure de lire le code après, et je crois personnellement les souffre de lisibilité lorsque cela se produit

La LINQ à la version XML utilise ci-dessus ne jamais les chaînes de données pures - les noms des éléments, etc - et utilise le code (appels de méthode) pour représenter des actions telles que « trouver des éléments avec un nom donné » ou « appliquer ce filtre ». C'est plus idiomatiques code C #, à mon avis.

Il est évident que d'autres ne partagent pas ce point de vue, mais je pense qu'il vaut la peine en expansion à montrer où je viens.

Notez que ce n'est pas un dur et rapide règle bien sûr ... dans certains cas, XPath, expressions régulières, etc sont la meilleure solution. Dans ce cas, je préfère le LINQ à XML, qui est tout.


1 Bien sûr, je peut ont gardé chaque appel Console.WriteLine sur une seule ligne, mais je ne aime pas le code d'affichage avec des barres de défilement horizontales sur SO. Notez que l'écriture de la version XPath correcte avec la même empreinte que ce qui précède et en évitant le défilement est encore assez méchant:

            Console.WriteLine(nav.SelectSingleNode("/GeocodeResponse/result/" +
                "address_component[type='administrative_area_level_1']" +
                "/short_name").InnerXml);

En général, les longues lignes fonctionnent beaucoup mieux dans Visual Studio qu'ils ne le font sur Stack Overflow ...

Je recommande simplement de taper l'expression XPath dans le cadre d'un fichier XSLT dans Visual Studio . Vous obtiendrez des messages d'erreur "que vous tapez" - c'est un excellent XML / XSLT / XPath éditeur

.

Par exemple, je suis en tapant:

<xsl:apply-templates select="@* | node() x"/>

et obtenir immédiatement dans la fenêtre Liste d'erreurs l'erreur suivante :

Error   9   Expected end of the expression, found 'x'.  @* | node()  -->x<--

XSLTFile1.xslt  9   14  Miscellaneous Files

uniquement lorsque l'expression XPath ne soulève pas d'erreurs (je pourrais aussi tester sélectionne les noeuds souhaités, aussi), je mettrais cette expression dans mon code C # .

Cela garantit que je n'aurai XPath - syntaxe et sémantique -. Erreurs lors je lance le programme C #

La réponse de DTB est exacte. Je voulais ajouter que vous pouvez utiliser XPath tester des outils comme le lien ci-dessous pour aider à trouver le XPath correct:

http://www.bit-101.com/xpath/

string url = @"http://maps.google.com/maps/api/geocode/xml?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false";
string value = "administrative_area_level_1";

using(WebClient client = new WebClient())
{
    string wcResult = client.DownloadString(url);

    XDocument xDoc = XDocument.Parse(wcResult);

    var result = xDoc.Descendants("address_component")
                    .Where(p=>p.Descendants("type")
                                .Any(q=>q.Value.Contains(value))
                    );

}

Le résultat est une énumération des « address_component » s qui ont au moins un noeud « type » qui a contient la valeur que vous cherchez. Le résultat de la requête ci-dessus est un XElement qui contient les données suivantes.

<address_component>
  <long_name>California</long_name>
  <short_name>CA</short_name>
  <type>administrative_area_level_1</type>
  <type>political</type>
</address_component> 

Je recommande vraiment passer un LINQ d'apprentissage peu de temps en général, car il est très utile pour la manipulation et l'interrogation des objets en mémoire, l'interrogation des bases de données et tend à être plus facile que d'utiliser XPath lorsque vous travaillez avec XML. Mon site préféré de référence est http://www.hookedonlinq.com/

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top