2010-02-26 5 views
1

J'essaye d'identifier tous les nœuds dans un arbre qui mènent à un nœud spécifique.alternative à l'ancêtre-ou-soi (ou sélectionnez tous les nœuds dans l'arborescence avec un nœud enfant spécifique)

J'essaye d'accomplir ceci par MSSQL XML (2005) ou par le Microsoft.XMLDOM dans l'ASP classique.

Je sais la logique avec XPath mais SQL Server ne prend pas en charge l'axe ancestor-or-self et XMLDOM semble étouffer la notation :: ..

Le XPath qui fonctionne quand je le tester dans les testeurs XPATH est

//static[@id=6]/ancestor-or-self::static 

mon XML (généré récursive dans le serveur SQL) ressemble

<root> 
    <static id="1" title="some title 1" /> 
    <static id="2" title="some title 2"> 
    <children> 
     <static id="3" title="some title 3" /> 
     <static id="4" title="some title 4"> 
      <children> 
      <static id="5" title="some title 5" /> 
      <static id="6" title="some title 6" /> 
      </children> 
     </static> 
    </children> 
    </static> 
    <static id="7" title="some title 7" /> 
</root> 

XPath doit sélectionner des noeuds avec id (2, 4,6) dans n'importe quel ordre, donc je peux ajouter un attribut à tous.

Ceci est pour un système de menu, où je ne connais que la feuille sélectionnée, et doit marquer comme hilited tous les nœuds menant à il ..

J'apprécierait toute aide soit surmonter XMLDOM étouffement (en cours d'exécution xml.documentElement.selectNodes("//static[@id=6]/ancestor-or-self::static") produit l'erreur suivante: Expected token 'eof' found ':'. //static[@id=6]/ancestor-or-self-->:<--:static)

ou à trouver une solution alternative. Peut-être trouver tous les nœuds qui contiennent le nœud spécifique (avec id = 6) à n'importe quelle profondeur ..

+0

solution alternative en termes de quoi? un nouveau parseur, un xpath différent, ou un langage de programmation différent? –

+0

@Jimmy, toute alternative, à l'exception des technologies changeantes, puisque le projet est déjà en cours. –

+1

Quelle version de XMLDocument utilisez-vous dans la partie ASP classique de l'implémentation? –

Répondre

1

En cours d'exécution sur W2K3, en utilisant IIS6 j'ai testé la version MSXML2.XMLDomDocument.4.0.

Dim XMLDom ''# As MSXML2.DOMDocument40 

Set XMLDom = CreateObject("MSXML2.DOMDocument.4.0") 
Call XMLDom.setProperty("SelectionLanguage", "XPath") 

Call XMLDom.loadXML({document as described above - mistakes in original xml doc) 
) 


Dim originalQuery ''# As String 
originalQuery = "//static[@id=6]/ancestor-or-self::static" 

Dim replacementQuery ''# As String 
replacementQuery = "//static[descendant::static[@id=6] or @id=6]" 


Dim XmlElemList ''# As MSXML2.IXMLDOMNodeList 
Set XmlElemList = XMLDom.documentElement.selectNodes(originalQuery) 

Dim XmlElemList2 ''# As MSXML2.IXMLDOMNodeList 
Set XmlElemList2 = XMLDom.documentElement.selectNodes(replacementQuery) 

Dim XmlElem ''# As MSXML2.IXMLDOMElement 
Call Response.Write("Using original query : '" & originalQuery & "' (" & XmlElemList.Length & ")<br>") 
For Each XmlElem In XmlElemList 
    Call Response.Write("XmlEntry : " & XmlElem.getAttribute("id") & "<br>") 
    Call Response.Write("****<br>") 
Next 

Call Response.Write("Using replacement query : '" & replacementQuery & "' (" & XmlElemList2.Length & ")<br>") 
For Each XmlElem In XmlElemList2 
    Call Response.Write("XmlEntry : " & XmlElem.getAttribute("id") & "<br>") 
    Call Response.Write("****<br>") 
Next 
+0

Oui, cela semble être le problème .. le changer en version 4 ou 5 a fait l'affaire ... Merci beaucoup :) * J'utilisais le 'Microsoft.XMLDOM' qui chargeait la version 2: o * –

4

Voici une sorte de «ranger les extrémités libres». D'abord, votre premier problème serait que Microsoft.XMLDOM chargerait normalement l'implémentation de la version 3.0 (MSXML3.dll). MSXML3 prend en charge le langage XPATH 1.0 complet, mais pas par défaut. Le suivi devrait être suffisant pour fixer: -

dom.SetProperty "SelectionLanguage", "XPath" 

réponse Marvin comprend cette ligne lors de l'utilisation MSXML4 mais il est pas vraiment nécessaire puisque XPath est la langue de sélection par défaut sur 4 et au-dessus.

Cependant, j'utilise le mot ci-dessus ci-dessus. J'ai souvent rencontré des serveurs qui ont été compromis par une application tierce qui inclut également une distribution de MSXML2 mais l'installe incorrectement. Ils provoquent "Microsoft.XMLDOM" et "MSXML2.DOMDocument" non spécifique à la version pour renvoyer une implémentation MSXML2.dll au lieu d'implémentations MSXML3.

Je recommande donc normalement que le meilleur ProgID à utiliser soit "MSXML2.DOMDocument.3.0" puisque vous savez exactement ce que vous obtenez. En outre MSXML3.dll est garanti pour être installé sur tous les systèmes d'exploitation Windows actuellement pris en charge dans la boîte. MSXML3 est également resté compatible avec les bogues dans l'implémentation MSXML2 lorsque le document DOM est appelé en utilisant un progID plus ancien. L'utilisation du fichier ProgID spécifique à la version entraîne la conformité plus stricte de MSXML3 aux normes XML.

+0

+1, Excellente info là Anthony, merci pour le suivi .. (* devrait-il être compris et non compromis? *) –

+0

Les défauts sont mauvais! Ils semblent changer au fil du temps. Supposons qu'il n'y ait aucune question quelle langue de sélection son utilisation en atteignant XML 10.0;) –

+0

@Marvin: Defaults sont grands ils certainement pas mal, sans défaut notre code serait beaucoup plus difficile à écrire. Par exemple, vos XPaths dans votre code journalier sont-ils parsemés de 'child ::' pour éviter de se fier au fait que 'child ::' est l'axe __default__ utilisé par XPath? Je mets ces réponses «en ordre» pour m'assurer qu'il n'y a pas de mauvaise conception de ce qui se passe vraiment. Il se pourrait que votre code précise que spécifier XPath est nécessaire, ce n'est pas le cas. Cependant, je suis d'accord qu'il y a un certain confort qui vient d'être explicite à ce sujet de toute façon. – AnthonyWJones

Questions connexes