delphi
  • xpath
  • msxml
  • 2009-10-05 8 views 4 likes 
    4

    j'ai chargé un document XML, et maintenant je souhaite exécuter une requête XPath pour sélectionner un sous-ensemble de XML. Le XML estDelphi/MSXML: requêtes XPath ne

    <?xml version="1.0"?> 
    <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> 
        <book id="bk101"> 
         <author>Gambardella, Matthew</author> 
         <title>XML Developer's Guide</title> 
         <genre>Computer</genre> 
         <price>44.95</price> 
         <publish_date>2000-10-01</publish_date> 
         <description>An in-depth look at creating applications with 
         XML.</description> 
        </book> 
    </catalog> 
    

    et la procédure est quelque chose comme

    procedure RunXPathQuery(XML: IXMLDOMDocument2; Query: string); 
    begin 
    
        XML.setProperty('SelectionLanguage', 'XPath'); 
    
        NodeListResult := XML.documentElement.selectNodes(Query)); 
    
        ShowMessage('Found (' + IntToStr(NodeListResult.length) + ') nodes.'); 
    
    end; 
    

    problème est: quand je lance la requête XPath «/catalogue » pour le XML ci-dessus, il retourne (comme prévu) Nodelist de 1 élément Toutefois, si je supprime :xsi de <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> et relancez la requête, la nodelist renvoyée est vide. Si je supprime l'attribut entier 'xmlns', la nodelist résultante a, encore une fois, 1 élément. Donc ma question est la suivante: que puis-je faire pour y remédier, c'est-à-dire comment faire en sorte que MSXML renvoie le nombre correct d'instances (lors de l'exécution d'une requête XPath), indépendamment de l'espace de noms (ou autres attributs)?

    Merci!

    +0

    Soit je lis ceci (http://support.microsoft.com/kb/288147) tout à fait tort, ou il est impossible d'utiliser un espace de noms par défaut avec XPath pour certaines versions de MSXML. Malheureusement, j'utilise MSXML v6.0, cela ne devrait donc pas m'affecter. Quelqu'un a eu des expériences similaires? – conciliator

    Répondre

    3

    Voir this link!

    Lorsque vous utilisez <catalog xmlns='http://www.w3.org/2001/XMLSchema-instance'> le nœud entier sera déplacé vers un autre espace de noms (par défaut). Votre XPath ne regarde pas à l'intérieur de cet autre espace de noms, il ne peut donc pas trouver de données. Avec <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>, vous déclarez simplement xsi en tant qu'espace de noms différent. Ce serait un espace de noms différent de l'espace de noms par défaut.

    Je ne peux pas le tester en ce moment, mais en ajoutant quelque chose like this pourrait aider:

    XML.setProperty('SelectionNamespaces', 'xmlns=''http://www.w3.org/2001/XMLSchema-instance'''); 
    

    Ou peut-être ne fonctionne pas. Comme je l'ai dit, je ne peux pas le tester maintenant.

    +0

    Merci Atelier Alex! Cela a du sens. Malheureusement, ça ne semble pas faire l'affaire (encore), mais je vais jouer avec ça un peu plus. – conciliator

    1

    Utilisation:

    document.setProperty('SelectionNamespaces', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"') 
    
    +0

    ... puis lancez une requête pour '/ xsi: catalog' au lieu de'/catalog'. –

    2

    figured it out. Il semble que mon problème a été décrit here et here (et probablement un zillion d'autres endroits, aussi).

    La requête/* [local-name() 'catalogue' =] fonctionne pour moi.

    0
    /*[local-name()='catalog'] 
    

    est une solution à votre question. Mais pourquoi voudriez-vous ignorer les espaces de noms? Ils ont été introduits pour exprimer quelque chose, par ex. distinguer différents types de catalogues. Avec votre requête, vous pouvez maintenant sélectionner le contenu de n'importe quel catalogue dans le monde, mais je suppose que vous ne pouvez gérer que des livres. Qu'est-ce qui se passera si vous obtenez un catalogue de vis ou de voitures à la place?

    Les choses mentionnées sur le préfixe (XSI) est correct. Si vous supprimez le préfixe, tous les éléments sont dans cet espace de noms (appelé espace de nom par défaut). Mais vous pouvez toujours y faire face.

    Dans votre code, donnez un préfixe à l'espace de nommage de toute façon. Il n'a même pas besoin de correspondre au préfixe d'origine:

    XML.setProperty('SelectionNamespaces', "xmlns:xyz='http://www.w3.org/2001/XMLSchema-instance'"); 
    

    La deuxième chose est d'adapter la requête XPath.Il doit alors être

    /xyz:catalog 
    

    Le fichier XML original déclare uniquement l'espace de noms xsi, mais ne l'utilise jamais. Dans ce cas, vous pouvez le supprimer complètement. Si vous voulez utiliser l'espace de noms et que vous voulez avec des préfixes, puis réécrire votre XML à

    <?xml version="1.0"?> 
    <xsi:catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> 
        <xsi:book id="bk101"> 
        <xsi:author>Gambardella, Matthew</xsi:author> 
        <xsi:title>XML Developer's Guide</xsi:title> 
        <xsi:genre>Computer</xsi:genre> 
        <xsi:price>44.95</xsi:price> 
        <xsi:publish_date>2000-10-01</xsi:publish_date> 
        <xsi:description>An in-depth look at creating applications with 
        XML.</xsi:description> 
    </xsi:book> 
    </xsi:catalog> 
    
    Questions connexes