ChatGPT解决这个技术问题 Extra ChatGPT

Getting attribute using XPath

Given an XML structure like so:

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

How could I get the value of lang (where lang is eng in book title), for the first element?


D
Dimitre Novatchev

How could I get the value of lang (where lang=eng in book title), for the first element?

Use:

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

This means:

Select the lang attribute of the title element that is a child of the first book child of the top element of the XML document.

To get just the string value of this attribute use the standard XPath function string():

string(/*/book[1]/title/@lang)

@AbhishekAsthana, The result of evaluating the XPath expression produces exactly the string value of the lang attribute. If the attribute doesn't contain any square brackets, they will not be part of the result of the evaluation of the XPath expression. My guess is that these are added by an (inappropriate) tool you are using.
yeah i figured out the problem..that's just how soapUI displays it but those brackets are not used when i use the xpath value. I have see this a lot of time. The problem is not with the tool..its between the chair and the keyboard.
@KorayTugay, the XPath expression /*/book[1]/title/@lang selects a node-set of 0 or more attribute nodes, while the XPath expression string(/*/book[1]/title/@lang) when evaluated, produces the string value of this node-set -- and this is the string value of the first (in document order) node from this node-set.
@KorayTugay, No, the first expression selects, doesn't "return" -- a set of nodes, and this set of nodes is not a string. A node is not a string -- a node is a node in a tree. An XML document is a tree of nodes. lang="eng" is just one of many textual representations of an attribute node that has a name "lang", doesn't belong to a namespace, and has a string value the string "eng"
@Vladimir, If the v corresponds to a namespace-uri of say: "my:vvv", then one can create in the host of the XPath engine being used a mapping associating myPrefix (may be v but not necessary) to the same namespace-uri "my:vvv". And then the attribute will be selected using: title/@myPrefix:lang. How such a mapping is created is implementation-specific and one has to read in the documentation of the host of the XPath engine. This is done in a specific way in .NET and in another way in let's say in Saxon. If you don't have any such mapping, use: title/@*[name()='v:lang']
M
Mathias Müller

Thanks! This solved a similar problem I had with a data attribute inside a Div.

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

Use this xpath: //*[@id="prop_sample"]/@data-want

Hope this helps someone else!


S
Sharath

You can try below xPath pattern,

  XPathExpression expr = xPath.compile("/bookstore/book/title[@lang='eng']")

That will select any XML title elements under /bookstore/book which have a lang Attribute with the value eng, NOT the value of lang. i.e. it selects a list of elements, not a single Attribute
R
Royce

If you are using PostgreSQL, this is the right way to get it. This is just an assumption where as you have a book table TITLE and PRICE column with populated data. Here's the query

SELECT xpath('/bookstore/book/title/@lang', xmlforest(book.title AS title, book.price AS price), ARRAY[ARRAY[]::TEXT[]]) FROM book LIMIT 1;

佚名

The standard formula to extract the values of attribute using XPath is

elementXPath/@attributeName

So here is the xpath to fetch the lang value of first attribute-

//title[text()='Harry Potter']/@lang

PS: indexes are never suggested to use in XPath as they can change if one more title tag comes in.


V
Vinod Srivastav

You can also get it by

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

although if you are using XMLDOM with JavaScript you can code something like

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

and n1.text will give you the value "eng"


s
starcwl

you can use:

(//@lang)[1]

these means you get all attributes nodes with name equal to "lang" and get the first one.


v
vtd-xml-author

Here is the snippet of getting the attribute value of "lang" with XPath and 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());
    }
}