2011-10-27 7 views
5

Użyłem XPath, aby wybrać węzeł z największą wartość całkowitą id przed użyciem tej kwerendy:Jak wybrać węzeł XML z najdłuższą wartością węzła #text węzła z XPath?

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

Miałem nadzieję, że mogę zrobić coś podobnego jak:

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

ale zwraca kilka węzłów zamiast jednego.

Sample XML:

<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> 

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

Odpowiedz

2

Element poszukiwany (y) nie mogą być wybierane za pomocą jednego XPath 1.0 ekspresji, ponieważ w XPath 1.0 nie jest możliwe do zastosowania funkcja do wszystkich wybranych węzłów (string-length(someNodeSet) jest stosowana tylko w pierwszym węźle tego zestawu węzłów). Innym powodem jest to, że w XPath 1.0 nie jest możliwe nazwanie i odniesienie zmiennych zmiennych.

W Xpath 2.0 jest trywialne:

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

Powyższe powoduje wybranie wszystkich entry elementów, których długość jest łańcuch, którego wartość maksymalna jeden.

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

Powyższe wybiera pierwszy (w kolejności dokumentów) taki element entry.

XSLT 2.0 - weryfikacja na podstawie:

Ta przemiana:

<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> 

po naniesieniu na dostarczonym dokumencie XML:

<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> 

wybiera entry elementy (w w tym przypadku tylko jeden) z t on maksymalny ciąg długości i wyprowadza wybrane elementy:

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

Myślę, że czegoś brakuje w tym drugim Query '[1]' na końcu może być? – travis

+0

@travis: Dobry połów - jestem trochę nieostry tego wieczoru. Poprawione. –

+2

+1 - * "(długość łańcucha (someNodeSet) jest stosowana tylko w pierwszym węźle tego zestawu węzłów)" * - Zrobiłem głupi błąd, a następnie zostałem zmylony przez zbyt mało przypadków testowych. To jest najlepsza odpowiedź. –

Powiązane problemy