Как я могу получить доступ к атрибутам XML в FireFox, используя XPath? - PullRequest
0 голосов
/ 25 мая 2019

Я не могу найти правильный метод JavaScript для доступа к нужным значениям атрибута из XML-файла, используя XPath в FireFox. Вот пример XML:

<book category="cooking">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>30.00</price>
</book>

<book category="children">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>

Я просмотрел другие ответы на предыдущие вопросы ( Получение атрибутов с использованием XPath ), но я не могу адаптировать их для работы с моим кодом.

Вот что я использую (взято с сайта w3schools):

<html>
<body>

<p id="demo"></p>
<p id="demo2"></p>

<script>
// from here: https://www.w3schools.com/xml/tryit.asp?filename=try_xpath_select_cdnodes
// new xmlhttprequest object
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        //call showResult function, pass response to request to it (i.e. the page we want to scrape)
        showResult(xhttp.responseXML);
    }
};
// initialise request with method and URL
xhttp.open("GET", "book.html", true);
// run request
xhttp.send(); 

// function to get xpath result, interate over it and write to paragraph tag with demo id
function showResult(xml) {
    var txt = "";
    //this is the xpath bit, the code to grab the tag values we want
    path = "/bookstore/book/title"
    if (xml.evaluate) {
        var nodes = xml.evaluate(path, xml, null, XPathResult.ANY_TYPE, null);
        var result = nodes.iterateNext();
        while (result) {
            txt += result.childNodes[0].nodeValue + "<br>";
            result = nodes.iterateNext();
        } 
    // Code For Internet Explorer
    } else if (window.ActiveXObject || xhttp.responseType == "msxml-document") {
        xml.setProperty("SelectionLanguage", "XPath");
        nodes = xml.selectNodes(path);
        for (i = 0; i < nodes.length; i++) {
            txt += nodes[i].childNodes[0].nodeValue + "<br>";
        }
    }
    document.getElementById("demo").innerHTML = txt;
}

</body>
</html>

Возвращает итальянец, Гарри Поттер. Я хотел бы адаптироваться, чтобы вернуть en, en.

Оцените, что текущий код работает должным образом, я просто не могу понять, куда поместить что-то вроде метода getAttributes. Я не очень понимаю, почему цикл firefox использует метод childNodes. Спасибо.

1 Ответ

1 голос
/ 25 мая 2019

В терминах XPath, если вы хотите выбрать все атрибуты этих элементов, используйте путь /bookstore/book/title/@*, если вы хотите выбрать эти lang атрибуты, используйте /bookstore/book/title/@lang.

В API XPathс помощью метода evaluate (https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate) и метода iterateNext (https://developer.mozilla.org/en-US/docs/Web/API/XPathResult/iterateNext)) вы можете просто использовать

    var xpathResult = xml.evaluate(path, xml, null, XPathResult.ANY_TYPE, null);
    var node = null;
    while ((node = xpathResult.iterateNext()) != null) {
        txt += node.nodeValue + "<br>";
    } 

var xmlCode = `<bookstore>
<book category="cooking">
  <title lang="en">Everyday Italian</title>
  <author>Giada De Laurentiis</author>
  <year>2005</year>
  <price>30.00</price>
</book>

<book category="children">
  <title lang="en">Harry Potter</title>
  <author>J K. Rowling</author>
  <year>2005</year>
  <price>29.99</price>
</book>
</bookstore>`;


var xml = new DOMParser().parseFromString(xmlCode, 'application/xml');

var path = '/bookstore/book/title/@lang';

var xpathResult = xml.evaluate(path, xml, null, XPathResult.ANY_TYPE, null);
    
var node = null;

var values = [];

while ((node = xpathResult.iterateNext()) != null) {
  values.push(node.nodeValue);
}

document.getElementById('demo').innerHTML = values.join('<br>');
<p id="demo"></p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...