Разбор XML переменной строки в JavaScript

199

У меня есть строка variable, которая содержит хорошо сформированный и действительный XML. Мне нужно использовать код JavaScript для синтаксического анализа этого фида.

Как я могу выполнить это с помощью (совместимого с браузером) кода JavaScript?

Теги:
parsing

12 ответов

83
Лучший ответ

Обновление. Для получения более правильного ответа см. Ответ Tim Down.

Internet Explorer и, например, браузеры на основе Mozilla предоставляют разные объекты для синтаксического анализа XML, поэтому разумно использовать инфраструктуру JavaScript, например jQuery для обработки различий между браузерами.

На самом деле основным примером является:

var xml = "<music><album>Beethoven</album></music>";

var result = $(xml).find("album").text();

Примечание. Как отмечалось в комментариях; jQuery на самом деле не разбирает какой-либо XML-анализ, он полагается на метод DOM innerHTML и будет анализировать его так, как если бы любой HTML-код был осторожен при использовании имен HTML-элементов в вашем XML-документе. Но я думаю, что это работает достаточно хорошо для простого XML-анализа, но это, вероятно, не рекомендуется для интенсивного или "динамического" разбора XML, где вы не планируете, какой XML будет снижаться, и это проверяет, все ли все анализирует, как ожидалось.

  • 6
    Код для абстрагирования различий в разборе XML между IE и другими браузерами состоит из нескольких тривиальных строк, поэтому не стоит использовать jKuery на 50 Кбайт. Манипулирование получающейся в результате DOM XML - это другой вопрос.
  • 7
    И что-то, чего я не осознавал во время публикации моего предыдущего комментария, это то, что jQuery даже не анализирует XML, он просто назначает его как свойство innerHTML элемента, что вовсе не надежно.
Показать ещё 6 комментариев
291

Обновленный ответ за 2017 год

Следующее проанализирует XML-строку в XML-документе во всех основных браузерах. Если вам не нужна поддержка IE <= 8 или некоторого неясного браузера, вы можете использовать следующую функцию:

function parseXml(xmlStr) {
   return new window.DOMParser().parseFromString(xmlStr, "text/xml");
}

Если вам нужно поддерживать IE <= 8, следующее будет выполняться:

var parseXml;

if (typeof window.DOMParser != "undefined") {
    parseXml = function(xmlStr) {
        return new window.DOMParser().parseFromString(xmlStr, "text/xml");
    };
} else if (typeof window.ActiveXObject != "undefined" &&
       new window.ActiveXObject("Microsoft.XMLDOM")) {
    parseXml = function(xmlStr) {
        var xmlDoc = new window.ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(xmlStr);
        return xmlDoc;
    };
} else {
    throw new Error("No XML parser found");
}

Когда у вас есть Document полученный с помощью parseXml, вы можете использовать обычные методы/свойства обхода DOM, такие как childNodes и getElementsByTagName() чтобы получить childNodes вам узлы.

Пример использования:

var xml = parseXml("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);

Если вы используете jQuery, из версии 1.5 вы можете использовать встроенный метод parseXML(), который функционально идентичен функции выше.

var xml = $.parseXML("<foo>Stuff</foo>");
alert(xml.documentElement.nodeName);
  • 54
    Я согласен, это должен быть принят ответ. Мой ответ очень старый с первых дней, и мне всегда было любопытно, что он все еще получает голоса. Кто-нибудь за удаление моего принятого ответа? И система голосования несовершенна? Упражни это народ!
  • 0
    @SanderVersluys: Вы можете удалить свой ответ?
Показать ещё 12 комментариев
19

Большинство примеров в Интернете (и некоторые из представленных выше) показывают, как загрузить XML из файла в браузере. Это легко доказывает, за исключением случая с Google Chrome, который не поддерживает метод document.implementation.createDocument(). При использовании Chrome для загрузки XML файла в объект XmlDocument вам необходимо использовать встроенный объект XmlHttp, а затем загрузить файл, передав его URI.

В вашем случае сценарий отличается, потому что вы хотите загрузить XML из строковой переменной, а не URL. Однако для этого требования Chrome предположительно работает так же, как Mozilla (или так я слышал), и поддерживает метод parseFromString().

Вот функция, которую я использую (это часть библиотеки совместимости браузера, которую я сейчас создаю):

function LoadXMLString(xmlString)
{
  // ObjectExists checks if the passed parameter is not null.
  // isString (as the name suggests) checks if the type is a valid string.
  if (ObjectExists(xmlString) && isString(xmlString))
  {
    var xDoc;
    // The GetBrowserType function returns a 2-letter code representing
    // ...the type of browser.
    var bType = GetBrowserType();

    switch(bType)
    {
      case "ie":
        // This actually calls into a function that returns a DOMDocument 
        // on the basis of the MSXML version installed.
        // Simplified here for illustration.
        xDoc = new ActiveXObject("MSXML2.DOMDocument")
        xDoc.async = false;
        xDoc.loadXML(xmlString);
        break;
      default:
        var dp = new DOMParser();
        xDoc = dp.parseFromString(xmlString, "text/xml");
        break;
    }
    return xDoc;
  }
  else
    return null;
}
  • 11
    -1 для просмотра браузера.
  • 16
    Я знаю о противоречивых мнениях относительно прослушивания браузера, и именно поэтому я не включил эту функцию здесь. Однако не было установлено, что это НЕПРАВИЛЬНО. В любом случае, это наводящий пример.
Показать ещё 2 комментария
13

Marknote - это легкий, легкий кросс-браузер JavaScript XML-парсер. Он объектно-ориентированный и содержит множество примеров, а также API. Это довольно новый, но он хорошо работал в одном из моих проектов. Единственное, что мне нравится в этом, это то, что он будет читать XML непосредственно из строк или URL-адресов, и вы также можете использовать его для преобразования XML в JSON.

Вот пример того, что вы можете сделать с помощью Marknote:

var str = '<books>' +
          '  <book title="A Tale of Two Cities"/>' +
          '  <book title="1984"/>' +
          '</books>';

var parser = new marknote.Parser();
var doc = parser.parse(str);

var bookEls = doc.getRootElement().getChildElements();

for (var i=0; i<bookEls.length; i++) {
    var bookEl = bookEls[i];
    // alerts "Element name is 'book' and book title is '...'"
    alert("Element name is '" + bookEl.getName() + 
        "' and book title is '" + 
        bookEl.getAttributeValue("title") + "'"
    );
}
  • 0
    Кажется, что marknote реализует чистый анализатор javascript. Это означает, что он должен быть совместим с любым движком JavaScript, где бы он ни использовался в браузере, в node.js или в автономном движке JavaScript ...
8

Очевидно, jQuery теперь предоставляет jQuery.parseXML http://api.jquery.com/jQuery.parseXML/ с версии 1.5

jQuery.parseXML( data ) Возвраты: XMLDocument

8

Я всегда использовал подход ниже, который работает в IE и Firefox.

Пример XML:

<fruits>
  <fruit name="Apple" colour="Green" />
  <fruit name="Banana" colour="Yellow" />
</fruits>

JavaScript:

function getFruits(xml) {
  var fruits = xml.getElementsByTagName("fruits")[0];
  if (fruits) {
    var fruitsNodes = fruits.childNodes;
    if (fruitsNodes) {
      for (var i = 0; i < fruitsNodes.length; i++) {
        var name = fruitsNodes[i].getAttribute("name");
        var colour = fruitsNodes[i].getAttribute("colour");
        alert("Fruit " + name + " is coloured " + colour);
      }
    }
  }
}
  • 0
    Как бы вы взяли ценность, если бы у вас была такая ситуация <fruit> value </ fruit>?
  • 1
    @Siblja вам нужно использовать innerText вместо getAttribute()
2

Пожалуйста, взгляните на XML DOM Parser (W3Schools). Это учебник по анализу XML DOM. Фактический парсер DOM отличается от браузера браузером, но DOM API стандартизирован и остается тем же (более или менее).

В качестве альтернативы используйте E4X, если вы можете ограничить себя в Firefox. Он относительно прост в использовании и является частью JavaScript с версии 1.6. Вот небольшой пример использования...

//Using E4X
var xmlDoc=new XML();
xmlDoc.load("note.xml");
document.write(xmlDoc.body); //Note: 'body' is actually a tag in note.xml,
//but it can be accessed as if it were a regular property of xmlDoc.
1

Я создал плагин jQuery, который легко анализирует XML. Он работает во всех браузерах Yahoo A и имеет параметры фильтрации, ограничения и обратного вызова.

Это может быть решение для рассмотрения: http://jparse.kylerush.net/

1

Предполагая, что вы хотите построить DOM из этого XML, к сожалению, вам нужно использовать интерфейсы, специфичные для браузера. Здесь - попытка использовать кросс-браузерную функцию для этого.

W3Schools также документировать индивидуальные методы, специфичные для браузера.

0

Отказ от ответственности: я создал fast-xml-parser

Я создал fast-xml-parser для синтаксического анализа XML-строки в объект JS/JSON или объект промежуточного обхода. Ожидается, что он будет совместим во всех браузерах (однако он протестирован только в Chrome, Firefox и IE).

Применение

var options = { //default
    attrPrefix : "@_",
    attrNodeName: false,
    textNodeName : "#text",
    ignoreNonTextNodeAttr : true,
    ignoreTextNodeAttr : true,
    ignoreNameSpace : true,
    ignoreRootElement : false,
    textNodeConversion : true,
    textAttrConversion : false,
    arrayMode : false
};

if(parser.validate(xmlData)){//optional
    var jsonObj = parser.parse(xmlData, options);
}

//Intermediate obj
var tObj = parser.getTraversalObj(xmlData,options);
:
var jsonObj = parser.convertToJson(tObj);

Примечание. Он не использует парсер DOM, но анализирует строку с помощью RE и преобразует ее в объект JS/JSON.

Попробуйте онлайн, CDN

0
<script language="JavaScript">
function importXML()
{
    if (document.implementation && document.implementation.createDocument)
    {
            xmlDoc = document.implementation.createDocument("", "", null);
            xmlDoc.onload = createTable;
    }
    else if (window.ActiveXObject)
    {
            xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
            xmlDoc.onreadystatechange = function () {
                    if (xmlDoc.readyState == 4) createTable()
            };
    }
    else
    {
            alert('Your browser can\'t handle this script');
            return;
    }
    xmlDoc.load("emperors.xml");
}

function createTable()
{
    var theData="";
    var x = xmlDoc.getElementsByTagName('emperor');
    var newEl = document.createElement('TABLE');
    newEl.setAttribute('cellPadding',3);
    newEl.setAttribute('cellSpacing',0);
    newEl.setAttribute('border',1);
    var tmp = document.createElement('TBODY');
    newEl.appendChild(tmp);
    var row = document.createElement('TR');
    for (j=0;j<x[0].childNodes.length;j++)
    {
            if (x[0].childNodes[j].nodeType != 1) continue;
            var container = document.createElement('TH');
            theData = document.createTextNode(x[0].childNodes[j].nodeName);
            container.appendChild(theData);
            row.appendChild(container);
    }
    tmp.appendChild(row);
    for (i=0;i<x.length;i++)
    {
            var row = document.createElement('TR');
            for (j=0;j<x[i].childNodes.length;j++)
            {
                    if (x[i].childNodes[j].nodeType != 1) continue;
                    var container = document.createElement('TD');
                    var theData = document.createTextNode(x[i].childNodes[j].firstChild.nodeValue);
                    container.appendChild(theData);
                    row.appendChild(container);
            }
            tmp.appendChild(row);
    }
    document.getElementById('writeroot').appendChild(newEl);
}
</script>
</HEAD>

<BODY onLoad="javascript:importXML();">
<p id=writeroot> </p>
</BODY>

Для получения дополнительной информации обратитесь к http://www.easycodingclub.com/xml-parser-in-javascript/javascript-tutorials/

-1

Вы также можете использовать функцию jquery ($. parseXML) для управления строкой xml

Пример javascript:

var xmlString = '<languages><language name="c"></language><language name="php"></language></languages>';
var xmlDoc = $.parseXML(xmlString);
$(xmlDoc).find('name').each(function(){
    console.log('name:'+$(this).attr('name'))
})

Ещё вопросы

Сообщество Overcoder
Наверх
Меню