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

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

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

10 ответов

Решение

Обновление: для более правильного ответа см. Ответ Тима Дауна.

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 выйдет из строя, и проверяет, все ли анализируется, как ожидалось.

Обновленный ответ на 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() чтобы получить узлы, которые вы хотите.

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

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

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

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

Большинство примеров в Интернете (и некоторые из представленных выше) показывают, как загрузить 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;
}

Marknote - это удобный легкий кросс-браузерный парсер XML 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") + "'"
    );
}

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

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

Я всегда использовал подход ниже, который работает в 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);
      }
    }
  }
}

Отказ от ответственности: я создал 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

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

В качестве альтернативы используйте 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.
<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/

Вы также можете с помощью функции 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'))
})
Другие вопросы по тегам