2011-10-27 18 views
5

Ho usato XPath per selezionare il nodo con il più grande valore intero id prima di utilizzare questa query:Come selezionare un nodo XML con il valore di nodo #text child più lungo con XPath?

//somenode[not(@id <= preceding::somenode/@id) and not(@id <= following::somenode/@id)] 

speravo che avrei potuto fare qualcosa di simile come:

//entry[not(string-length(child::text()) <= string-length(preceding::entry/child::text())) and not(string-length(child::text()) <= string-length(following::entry/child::text()))] 

ma restituisce un mucchio di nodi invece di uno solo.

XML

Esempio:

<xml> 
    <entry>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</entry> 
    <entry>Nam dignissim mi a massa mattis rutrum eu eget mauris.</entry> 
    <entry>Ut at diam a sem scelerisque pretium nec pulvinar purus.</entry> 
    <entry>Nunc in nisi nec dolor accumsan suscipit vel a quam.</entry> 
    <entry>Nunc suscipit lobortis arcu, nec adipiscing libero bibendum nec.</entry> 
    <entry>Aenean eget ipsum et nunc eleifend scelerisque.</entry> 
    <entry>In eu magna et diam volutpat molestie.</entry> 
    <entry>In volutpat luctus mi, eu laoreet orci dictum vel.</entry> 
    <entry>In mattis mi nec magna sodales eu bibendum felis aliquet.</entry> 
<!-- etc for 800 more lines or so --> 
    <entry>Duis auctor felis id neque gravida ut auctor ipsum ullamcorper.</entry> 
    <entry>Sed vel tortor mauris, et aliquet tellus.</entry> 
</xml> 

prova XPath: http://chris.photobooks.com/xml/default.htm?state=1o

risposta

2

L'elemento desiderata (s) non può essere selezionato con un singolo XPath 1.0 espressione, perché in XPath 1.0 non è possibile applicare una funzione per tutti i nodi selezionati (string-length(someNodeSet) viene applicata solo sul primo nodo di questo set di nodi). Un'altra ragione è che in XPath 1.0 non è possibile nominare e fare riferimento a variabili di intervallo.

In XPath 2.0 questo è banale:

/*/entry[not(string-length(.) &lt; /*/entry/string-length(.))] 

I suddetti seleziona tutti entry elementi della lunghezza di cui valore di stringa è quella massima.

/*/entry[not(string-length(.) &lt; /*/entry/string-length(.))] [1] 

Quanto sopra seleziona la prima (nell'ordine del documento) tale entry elemento.

XSLT 2.0 - verifica basata:

Questa trasformazione:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="/"> 
    <xsl:sequence select= 
    "/*/entry[not(string-length(.) &lt; /*/entry/string-length(.))]"/> 
</xsl:template> 
</xsl:stylesheet> 

se applicato sul documento XML fornito:

<xml> 
    <entry>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</entry> 
    <entry>Nam dignissim mi a massa mattis rutrum eu eget mauris.</entry> 
    <entry>Ut at diam a sem scelerisque pretium nec pulvinar purus.</entry> 
    <entry>Nunc in nisi nec dolor accumsan suscipit vel a quam.</entry> 
    <entry>Nunc suscipit lobortis arcu, nec adipiscing libero bibendum nec.</entry> 
    <entry>Aenean eget ipsum et nunc eleifend scelerisque.</entry> 
    <entry>In eu magna et diam volutpat molestie.</entry> 
    <entry>In volutpat luctus mi, eu laoreet orci dictum vel.</entry> 
    <entry>In mattis mi nec magna sodales eu bibendum felis aliquet.</entry> 
<!-- etc for 800 more lines or so --> 
    <entry>Duis auctor felis id neque gravida ut auctor ipsum ullamcorper.</entry> 
    <entry>Sed vel tortor mauris, et aliquet tellus.</entry> 
</xml> 

seleziona le entry elementi (in questo caso solo uno) con t egli massima stringa di lunghezza ed emette gli elementi selezionati:

<entry>Nunc suscipit lobortis arcu, nec adipiscing libero bibendum nec.</entry> 
+0

penso che ti manca qualcosa in quella seconda query, un '[1]' sulla fine forse? – travis

+0

@travis: Buona cattura - Sono un po 'fuori fuoco questa sera. Corretto. –

+2

+1 - * "(string-length (someNodeSet) viene applicato solo sul primo nodo di questo set di nodi)" * - Ho fatto un errore stupido e sono stato ingannato da troppi casi di test. Questa è la migliore risposta. –

Problemi correlati