Non è stato ansible trovare XPath dato da Chrome DevTools

Mentre stavo sperimentando alcuni percorsi XPG di SVG mentre rispondevo a un’altra domanda sul selenium, ho scoperto uno strano comportamento con XPath su Chrome (non ho provato su altri browser).

Su http://www.amcharts.com/svg-maps/?map=usa , perché XPath non funziona?

//*[@id="chartdiv"]/div/div[1]/svg/g[7]/g/g[1]

Considerando che questo fa ?

//*[@id="chartdiv"]/div/div[1]/*[name()="svg"]/*[name()="g"][7]/*[name()="g"]/*[name()="g"][2]


Ho dovuto apportare le seguenti modifiche:

  • /g diventa /*[name()="g"]
  • /svg diventa /*[name()="svg"]
  • /path diventa /*[name()="path"]

La cosa strana è che ho ottenuto il primo XPath facendo clic destro sull’elemento HTML e copiato l’XPath da lì.

inserisci la descrizione dell'immagine qui


Ho un altro esempio su http://gmsgroup.com/municenter.asp dove:

  • //*[@id='ext-gen203']/*[name()='svg']/*[name()='a']/*[name()='path'][starts-with(@d, 'M136.65')]/.. funziona,
  • //*[@id='ext-gen203']/*[name()='svg']/*[name()='a'][@title='Hawaii'] no.

Qui, /*[name()='a'][@title='Hawaii'] non è riuscito a ottenere , perché?

I namespace possono essere prefissati:

  

o namespace predefiniti:

  

SVG è in uno spazio dei nomi predefinito. Un’espressione di percorso come /svg dice a un processore XPath di cercare un elemento chiamato “svg” e che non è in alcun namespace. Pertanto, questa espressione corrisponde solo a:

  or  

Usando /*[name()='svg'] esclude solo uno spazio dei nomi prefissato. Permette comunque un elemento che si chiama “svg” e che si trova in uno spazio dei nomi predefinito, senza prefisso. Questa seconda espressione corrisponde

  

ma no

  

Per provarlo, considera il seguente foglio di stile XSLT:

       

Applicato al seguente input, un documento SVG abbreviato:

   

Risultati in:

   

Guardate voi stessi online qui .


EDIT (rispondendo al tuo commento)

Più chiaramente, vuol dire che lo spazio dei nomi predefinito SVG sovrascrive quello della pagina e quindi non gestisce espressioni come [@ title = ‘Hawaii’]?

Gli stessi elementi HTML non hanno uno spazio dei nomi e SVG non “sostituisce” lo spazio dei nomi della pagina. Lo spazio dei nomi predefinito sull’elemento svg si applica solo a se stesso ea tutti gli elementi figlio (incluso l’elemento a[@title='Hawaii'] al suo interno.

//*[@id='ext-gen203']/*[name()='svg']/*[name()='a'][@title='Hawaii'] dovrebbe essere in grado di trovare la a elemento e sono molto sorpreso che non lo faccia.

Dove trovare le specifiche per lo spazio dei nomi predefinito?

Se intendi lo spazio dei nomi predefinito in generale, guarda qui: http://www.w3.org/TR/REC-xml-names/#scoping-defaulting . Se intendevi la specifica SVG, studi il seguente capitolo delle specifiche SVG: http://www.w3.org/TR/SVG/struct.html .

Significa anche che non esiste un modo migliore per ottenere che // [@ id = ‘ext-gen203’] / [name () = ‘svg’] / [name () = ‘a’] / [nome () = ‘percorso’] [inizia-wit h (@d, ‘M136.65’)] / ..?

Il modo migliore per farlo è registrare o dichiarare tali spazi dei nomi e renderli quindi disponibili per l’uso nelle espressioni Xpath tramite prefissi (come ha sottolineato Martin Honnen). Chrome Dev Tools non è il mio campo di competenza, non posso commentare come farlo lì.

HTML5 e text / html consentono di combinare elementi HTML, MathML e SVG in un unico documento e non richiede di utilizzare gli spazi dei nomi associati ai diversi vocabolari. Con XPath, tuttavia, è necessario assicurarsi di associare un prefisso allo spazio dei nomi SVG e utilizzare tale prefisso nelle query, poiché nell’albero DOM gli elementi SVG si trovano in uno spazio dei nomi diverso rispetto agli elementi HTML. Che sia ansible all’interno dello strumento per sviluppatori, non lo so, ma con un’API ci sono in genere modi per impostare un risolutore dello spazio dei nomi che mappa i prefissi che si desidera utilizzare nelle espressioni XPath negli URL dello spazio dei nomi.