JavaScriptでの変数文字列のXML解析


204

可変文字列があります整形式と有効なXMLが含まれています。このフィードを解析するには、JavaScriptコードを使用する必要があります。

(ブラウザ互換の)JavaScriptコードを使用してこれをどのように達成できますか?

回答:


90

更新:より正確な回答については、Tim Downの回答を参照してください

Internet Explorerや、たとえばMozillaベースのブラウザーは、XML解析のためにさまざまなオブジェクトを公開しているため、jQueryのようなJavaScriptフレームワークを使用するのが賢明です。ブラウザー間の違いを処理するです。

本当に基本的な例は:

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

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

注:コメントで指摘されているとおり。jQueryは実際にはXML解析を一切行いません。DOMinnerHTMLメソッドに依存しており、他のHTMLと同様に解析するため、XMLでHTML要素名を使用する場合は注意してください。しかし、単純なXMLの「解析」にはかなりうまくいくと思いますが、どのXMLがダウンするかを前もって考えない集中型または「動的」なXML解析にはお勧めできません。


6
IEと他のブラウザーとの間のXML解析の違いを抽象化するためのコードは、ほんの数行なので、50KのjQueryをそのまま使用する価値はありません。結果のXMLのDOMの操作は別の問題です。
Tim Down

7
そして、以前のコメントを投稿したときに気づかなかったことは、jQueryはXMLを解析することさえせず、単にinnerHTML要素のプロパティとして割り当てるだけであり、まったく信頼できないということです。
Tim Down

JQueryはXML名前空間をサポートしないことに注意してください。参照してくださいzachleat.com/web/2008/05/10/selecting-xml-with-javascript
mikemaccana

10
この答えは間違っています。参照stackoverflow.com/questions/2124924/...stackoverflow.com/questions/2908899/...、@Timダウンの答えとjQueryのドキュメント自体、それは述べて:「メモをその[ jQuery()]パースHTML、ない XML」
クレセントフレッシュ

2
@SanderVersluys:著者が別の回答を受け入れていないので、@ TimDownの正しい回答にリンクする注記を回答に含めます。そうすれば、人々は正しい答えを理解するためにこれらすべてのコメントを読む必要がなくなります。
センスフル2012年

321

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);

56
私は同意します、これは受け入れられるべき答えです。私の答えは初期の頃から非常に古く、それがまだ賛成票を獲得することに興味を持っています。私の受け入れられた答えを削除することに賛成の誰か?そして、投票システムに欠陥がありますか?この人に賛成投票してください!
Sander Versluys、2011

@SanderVersluys:回答を削除できますか?
Witman、2012年

1
「他にまともな答えはない」と言ってあなたに反対票を投じなければなりませんでした。@SanderVersluysの回答は私の場合はうまくいきました。それについてまともでないことは、私にはわかりません。
エリック

2
@EricTurner:私はそれを支持し、サンダー自身が彼の答えを否認しました。jQueryドキュメントは$()、XML解析に使用しないように指示しています。コメントをもっと注意深く読んでください:それは単に多くの状況で機能しないだけです。
Tim Down

1
@DWoldrich:Webで両方の方法で見たことがあります。信頼できる回答に最も近いのはmsdn.microsoft.com/en-us/library/ms761398(v=vs.85).aspxで、ブール値を使用する必要があることを示しています。ただし、これにどの程度の値を設定するかは完全に自由でありparseXML()jQueryのメソッドは文字列を使用します。現在、簡単にテストする方法がないので、答えを変更することに少し注意します。
Tim Down

19

Web上のほとんどの例(および上記の例)は、ブラウザ互換の方法でファイルから XMLをロードする方法を示しています。これは、document.implementation.createDocument()メソッドをサポートしていないGoogle Chromeの場合を除いて、簡単です。Chromeを使用している場合、XMLファイルをXmlDocumentオブジェクトにロードするには、組み込みのXmlHttpオブジェクトを使用してから、そのURIを渡してファイルをロードする必要があります。

あなたの場合、URLではなく文字列変数から XMLをロードする必要があるため、シナリオは異なります。ただし、この要件については、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;
}

16
私はブラウザのスニッフィングに関して物議を醸している意見を認識しており、それが私がその機能をここに含めなかった理由です。しかし、それが間違っていることは確立されていません。いずれにせよ、これは示唆的な例です。
セレブラス2009年

1
私はそれが正しいことを保証できないという点で間違っていると信じています。誰もがUA文字列を偽装でき、IE以外のすべてのブラウザーがDOMParserをサポートしていること、およびブラウザーのスニッフィングが完全であることは疑わしいものです。それに、それはそれを正しい方法を行うためにはるかに簡単です:if(window.ActiveXObject){...}
1j01

IE9 + がDOMParserをサポートするようになりました。それをどのようにサポートしますか?@ 1j01が言っていることは-1。確認する必要があるのはだけvar dp; try{ dp = new DOMParser() } catch(e) { }; if(dp) { // DOMParser supported } else { // alert('you need to consider upgrading your browser\nOr pay extra money so developer can support the old versions using browser sniffing (eww)') }です。
アニー

13

Marknoteは、軽量でクロスブラウザのJavaScript XMLパーサーです。それはオブジェクト指向であり、多くの例があり、さらにAPIが文書化されています。かなり新しいものですが、これまでの私のプロジェクトの1つではうまく機能しています。私が気に入っている点の1つは、文字列またはURLから直接XMLを読み取り、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") + "'"
    );
}

marknoteは純粋なJavaScriptパーサーを実装しているようです。これは、ブラウザー、node.js、またはスタンドアロンのJavaScriptエンジンで使用される場所にかかわらず、JavaScriptエンジンと互換性があることを意味します...
Coyote

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);
      }
    }
  }
}

このような状況で<fruit> value </ fruit>があった場合、どのように値を取得しますか?
Siblja 2011

1
@SibljaのinnerText代わりに使用する必要がありますgetAttribute()
Manux22


2

XML DOM ParserW3Schools)をご覧ください。これは、XML DOM解析に関するチュートリアルです。実際のDOMパーサーはブラウザーによって異なりますが、DOM APIは標準化されており、ほぼ同じです(多かれ少なかれ)。

あるいは、Firefoxに限定できる場合はE4Xを使用してください。バージョン1.6以降、比較的使いやすく、JavaScriptの一部となっています。ここに小さなサンプルの使用法があります...

//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.

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/を参照してください


0

免責事項:私はfast-xml-parserを作成しました

XML文字列をJS / JSONオブジェクトまたは中間トラバーサルオブジェクトに解析するfast-xml-parserを作成しました。すべてのブラウザーで互換性があることが期待されます(ただし、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をオンラインでお試しください


-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'))
})
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.