Как получить значение определенного узла XML по пути? - PullRequest
5 голосов
/ 21 декабря 2010

Я ищу решение Javascript для этой проблемы:

У меня есть документ XML, который загружается с помощью типичного метода AJAX:

var xml = http.responseXML;

Рассмотрим следующий пример фрагмента xml:

<main>
    <primary>
         <enabled>true</enabled>
     </primary>
     <secondary>
         <enabled>true</enabled>
     </secondary>
 </main>

Я хотел бы получить значение узла, указав путь следующим образом:

var second_enabled = getNodeValueByPath('main/secondary/enabled', xml);

Я не могу найти какой-либо краткий способ сделать что-то подобное. Кажется, я вынужден перебирать коллекции узлов после использования getElementsByTagName и т. П.

Как бы я сконструировал метод getNodeValueByPath или в Javascript есть какая-то конструкция, позволяющая это сделать?

Я не очень хорошо разбираюсь в Javascript.

РЕДАКТИРОВАТЬ: Вот пример, который показывает мою попытку использования XPath и как он терпит неудачу:

XML:

<?xml version="1.0" ?>
<main xmlns="example.com">
  <primary>
    <enabled>true</enabled>
  </primary>
  <secondary>
    <enabled>false</enabled>
  </secondary>
</main>

JavaScript: (это только соответствующие функции)

function useHttpResponse()
{
    if (http.readyState == 4)
    {
        if(http.status == 200)
        {
            var xml = http.responseXML;
            var evalue = getXMLValueByPath('/main/secondary/enabled', xml);
            alert(evalue);
        }
    }
}

function getXMLValueByPath(nodepath, xml)
{
    var result = xml.evaluate(nodepath, xml, null, XPathResult.STRING_TYPE, null).stringValue;
    return result;
}

Я использую вышеупомянутый JavaScript без каких-либо дополнительных библиотек. Я использую Mozilla Firefox 3.6.13, который использует метод document.evaluate для выбора узлов (согласно этой информации из w3schools ). Это приложение предназначено для внутреннего использования и не должно работать в нескольких браузерах.

С учетом этих примеров появится диалоговое окно с предупреждением, но без текста. Если я удаляю строку xmlns="example.com" из документа XML, появляется диалоговое окно с текстом «false», если необходимо.

Отладка с использованием Firebug показывает, что resultNode является пустой строкой, пока объявлено пространство имен.

Ответы [ 4 ]

5 голосов
/ 28 декабря 2010

Это часто задаваемые вопросы: в XPath 1.0 тест QName без префикса выделяет элементы в пустом (или пустом) URI пространства имен. Поэтому вам нужно зарегистрировать префикс в URI пространства имен по умолчанию из вашего входного источника (example.com).

Как это сделать с DOM 3 XPath API?

С http://www.w3.org/TR/DOM-Level-3-XPath/xpath.html#XPathEvaluator-evaluate

evaluate
Оценивает XPath строка выражения и возвращает результат указанного типа, если это возможно.
Параметры
[...]
resolver типа XPathNSResolver
Решатель разрешает перевод всех префиксы, включая xml префикс пространства имен в XPath выражение в соответствующее пространство имен URIs. Если это указано как null, любой префикс пространства имен в пределах выражение приведет к DOMException бросается с код NAMESPACE_ERR.

А с https://developer.mozilla.org/en/DOM/document.evaluate

var xpathResult = document.evaluate(
 xpathExpression, 
 contextNode, 
 namespaceResolver, 
 resultType, 
 result);
  • namespaceResolver - это функция, которая будет передавать любые префиксы пространства имен и должна возвращать строку, представляющую URI пространства имен связанный с этим префиксом. Будет использоваться для разрешения префиксов внутри сам XPath, так что они могут быть сопоставляется с документом. null есть общий для документов HTML или когда нет используются префиксы пространства имен.

Следуя этой инструкции , вы можете использовать document.createNSResolver или функцию , например:

function nsResolver(prefix) {   
  return prefix == 'ex' ? 'example.com' : null;   
}  

function useHttpResponse()
{
  if (http.readyState == 4)
  {
     if (http.status == 200)
     {
        var xml = http.responseXML;
        var evalue = xml.evaluate('string(/ex:main/ex:secondary/ex:enabled)',
                                  xml,
                                  nsResolver,
                                  XPathResult.STRING_TYPE,
                                  null);
        alert(evalue.stringValue);
     }
  }
}     
1 голос
/ 21 декабря 2010
var xpathtosearchfor = '//div';
var result = new XPathEvaluator().evaluate(xpathtosearchfor,
    document.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);

В Firefox минимум

1 голос
/ 21 декабря 2010

Я играл с той же вещью, я пробовал несколько библиотек XPath JS, вот одна из них: http://js -xpath.sourceforge.net / , но, сказав это, я не смогЭто не работает, поэтому я буду внимательно следить за этим вопросом:)

Кроме того, на SO: Кросс-браузерная реализация XPath в JavaScript

0 голосов
/ 21 декабря 2010
XmlDocument xDoc = new XmlDocument();
xDoc.Load("d:\\one.xml");
XmlNode xNode = xDoc.SelectSingleNode(@"//main/secondary/enabled");
string result = ((XmlElement)xNode).FirstChild.Value;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...