Uzyskiwanie atrybutu za pomocą XPath

344

Biorąc pod uwagę taką strukturę XML:

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

<book>
  <title lang="eng">Harry Potter</title>
  <price>29.99</price>
</book>

<book>
  <title lang="eng">Learning XML</title>
  <price>39.95</price>
</book>

</bookstore>

Jak mogę uzyskać wartość lang(gdzie langjest engtytuł książki) dla pierwszego elementu?

GurdeepS
źródło
2
bardzo dobry link przy korzystaniu z xpaths test-able.blogspot.ie/2016/04/xpath-selectors-cheat-sheet.html

Odpowiedzi:

472

Jak uzyskać wartość lang (gdzie lang = eng w tytule książki) dla pierwszego elementu?

Użyj :

/*/book[1]/title/@lang

Oznacza to :

Wybierz langatrybut elementu tytułowego, który jest dzieckiem pierwszego bookelementu potomnego górnego elementu dokumentu XML.

Aby uzyskać tylko wartość ciągu tego atrybutu, użyj standardowej funkcji XPathstring() :

string(/*/book[1]/title/@lang)
Dimitre Novatchev
źródło
3
@AbhishekAsthana, Wynik oceny wyrażenia XPath daje dokładnie wartość ciągu langatrybutu. Jeśli atrybut nie zawiera nawiasów kwadratowych, nie będą one częścią wyniku oceny wyrażenia XPath. Domyślam się, że są one dodawane przez (nieodpowiednie) narzędzie, którego używasz.
Dimitre Novatchev
6
tak, zorientowałem się, jaki jest problem .. tak właśnie pokazuje mydło UI, ale te nawiasy nie są używane, gdy używam wartości xpath. Widziałem to dużo czasu. Problem nie dotyczy narzędzi… między krzesłem a klawiaturą.
Abhishek Asthana
4
@KorayTugay, wyrażenie XPath /*/book[1]/title/@lang wybiera zestaw węzłów o wartości 0 lub więcej węzłów atrybutów, a wyrażenie XPath string(/*/book[1]/title/@lang)po ocenie daje wartość ciągu tego zestawu węzłów - i jest to wartość ciągu pierwszego (w kolejności dokumentu) węzeł z tego zestawu węzłów.
Dimitre Novatchev
4
@KorayTugay, Nie, pierwsze wyrażenie wybiera , nie „zwraca” - zestaw węzłów, a ten zestaw węzłów nie jest łańcuchem. Węzeł nie jest łańcuchem - węzeł jest węzłem w drzewie . Dokument XML to drzewo węzłów. lang="eng"jest tylko jedną z wielu reprezentacji tekstowych węzła atrybutu, który ma nazwę „lang”, nie należy do przestrzeni nazw i ma wartość ciągu „eng”
Dimitre Novatchev
1
@Vladimir, jeśli v odpowiada przestrzeni nazw-uri powiedz: „my: vvv”, to w hoście silnika XPath można utworzyć odwzorowanie kojarzące myPrefix (może być v, ale nie konieczne) z tą samą przestrzenią nazw -uri „my: vvv”. A następnie atrybut zostanie wybrany za pomocą: title / @ myPrefix: lang. Sposób tworzenia takiego mapowania jest specyficzny dla implementacji i należy przeczytać w dokumentacji hosta silnika XPath. Odbywa się to w określony sposób w .NET i w inny sposób, powiedzmy w Saksonii. Jeśli nie masz takiego mapowania, użyj: title / @ * [name () = 'v: lang']
Dimitre Novatchev
47

Dzięki! To rozwiązało podobny problem, który miałem z atrybutem danych wewnątrz Div.

<div id="prop_sample" data-want="data I want">data I do not want</div>

Użyj tej ścieżki xpath: //*[@id="prop_sample"]/@data-want

Mam nadzieję, że to pomoże komuś innemu!

smulldino
źródło
6

Możesz wypróbować poniżej wzorca xPath,

  XPathExpression expr = xPath.compile("/bookstore/book/title[@lang='eng']")
Sharath
źródło
5
Spowoduje to wybranie dowolnego elementu tytułu XML w katalogu / bookstore / book, który ma atrybut lang o wartości eng, a NIE wartość lang. tzn. wybiera listę elementów, a nie pojedynczy Atrybut
JFK
2

Możesz go również zdobyć

string(//bookstore/book[1]/title/@lang)    
string(//bookstore/book[2]/title/@lang)

chociaż jeśli używasz XMLDOM z JavaScript, możesz napisać coś takiego

var n1 = uXmlDoc.selectSingleNode("//bookstore/book[1]/title/@lang");

i n1.textda ci wartość"eng"

Vinod Srivastav
źródło
2

możesz użyć:

(//@lang)[1]

oznacza to, że otrzymujesz wszystkie węzły atrybutów o nazwie równej „lang” i otrzymujesz pierwszy.

starcwl
źródło
0

Oto fragment otrzymywania wartości atrybutu „lang” za pomocą XPath i VTD-XML.

import com.ximpleware.*;
public class getAttrVal {
    public static void main(String s[]) throws VTDException{
        VTDGen vg = new VTDGen();
        if (!vg.parseFile("input.xml", false)){
            return ;
        }
        VTDNav vn = vg.getNav();
        AutoPilot ap = new AutoPilot(vn);
        ap.selectXPath("/bookstore/book/title/@lang");
        System.out.println(" lang's value is ===>"+ap.evalXPathToString());
    }
}
vtd-xml-autor
źródło
0

Jeśli używasz PostgreSQL, jest to właściwy sposób na zdobycie go. Jest to tylko założenie, w którym jak masz tabelę książek TITLE i PRICE kolumna z wypełnionymi danymi. Oto zapytanie

SELECT xpath('/bookstore/book/title/@lang', xmlforest(book.title AS title, book.price AS price), ARRAY[ARRAY[]::TEXT[]]) FROM book LIMIT 1;
Royce
źródło