네임 스페이스로 XML 구문 분석에 jQuery를 사용하는 방법


82

저는 jQuery를 처음 사용하며 XML 문서를 구문 분석하고 싶습니다.

기본 네임 스페이스를 사용하지만 다음과 같은 XML을 사용하여 일반 XML을 구문 분석 할 수 있습니다.

<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
   <s:Schema id="RowsetSchema">
     <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">
       <s:AttributeType name="ows_ID" rs:name="ID" rs:number="1">
        <s:datatype dt:type="i4" dt:maxLength="4" />
      </s:AttributeType>
       <s:AttributeType name="ows_DocIcon" rs:name="Type" rs:number="2">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
       <s:AttributeType name="ows_LinkTitle" rs:name="Title" rs:number="3">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
       <s:AttributeType name="ows_ServiceCategory" rs:name="Service Category" rs:number="4">
        <s:datatype dt:type="string" dt:maxLength="512" />
      </s:AttributeType>
    </s:ElementType>
  </s:Schema>
   <rs:data>
    <z:row ows_ID="2" ows_LinkTitle="Sample Data 1" />
    <z:row ows_ID="3" ows_LinkTitle="Sample Data 2" />
    <z:row ows_ID="4" ows_LinkTitle="Sample Data 3" />
  </rs:data>
</xml>

내가 정말로 원하는 것은 <z:row>.

지금까지 다음을 사용했습니다.

$.get(xmlPath, {}, function(xml) {
    $("rs:data", xml).find("z:row").each(function(i) {
        alert("found zrow");
    });
}, "xml");

정말 운이 없습니다. 어떤 아이디어?


네임 스페이스 접두사를 생략하면 효과가있었습니다. 이 답변보기 : stackoverflow.com/a/25089647/2539811
Vincil Bishop 2017 년

답변:


135

알았어.

\\콜론을 탈출 해야한다는 것이 밝혀졌습니다 .

$.get(xmlPath, {}, function(xml) {
    $("rs\\:data", xml).find("z\\:row").each(function(i) {
        alert("found zrow");
    });
}, "xml");

Rich는 다음과 같이 지적했습니다.

더 나은 솔루션은 이스케이프가 필요하지 않으며 모든 "최신"브라우저에서 작동합니다.

.find("[nodeName=z:row]")

2
$('[nodeName=rs:data]', xml).find('[nodeName=z:row]')- 웹킷에서 1.3.2로 작업 (여기서 탈출 대장 방법은 분명히하지 않습니다)
gnarf

2
이것은 jQuery 버전 1.4.4에서 작동을 멈춘 것 같습니다. 이는 jQuery가 더 나은 XML 네임 스페이스 지원을 제공한다는 것을 의미합니다. 안전을 위해이 작동합니다$('[nodeName=rs:data],data')
Josh Pearce 2011 년

15
이제 jQuery 1.7이 나왔고이 마지막 솔루션은 더 이상 작동하지 않습니다. 새로운 방법은 무엇입니까?
Gapipro 2011

3
jQuery 1.8.x에서는 더 이상 작동하지 않습니다. 여기에 설명 된대로 사용자 정의 의사 클래스 호환성 해결 방법으로 수행해야 합니다 .
Miere 2011 년

5
이 지정된 XML의 문서에 대한 질문에 대한 대답에도 불구하고 있음을, 나는 사람들을 생각 나게하고 싶습니다 접두사 처럼 rs, dt또는 s네임 스페이스가 정말 없습니다. 네임 스페이스는 파일 맨 위에있는 URN입니다. 접두사는 문서 작성자가 짧게 유지하기 위해 선택한 별칭입니다. 완전히 다른 접두사로 동일한 네임 스페이스와 일치하는 동일한 문서를 만들 수 있습니다. 모든 사람이 쿼리에서 접두사를 가정하는 대신 네임 스페이스를 이해하는 API를 찾도록 권장합니다. 예를 들어 브라우저 DOM API에서 getElementByTagNameNS()getAttributeNS().
sergiopereira

35

나는 운이없는 플러그인과 모든 종류의 솔루션에 대한이 독서에 몇 시간을 보냈습니다.

ArnisAndy는이 답변이 제공되는 jQuery 토론에 대한 링크를 게시했으며 이것이 Chrome (v18.0), FireFox (v11.0), IE (v9.08) 및 Safari (v5.1.5)에서 작동 함을 확인할 수 있습니다. ) jQuery (v1.7.2) 사용.

콘텐츠 이름이 <content : encoded> 인 WordPress 피드를 스크랩하려고하는데 이것이 저에게 효과적이었습니다.

content: $this.find("content\\:encoded, encoded").text()

3
이것은 최신 jQuery (동일 버전)를 사용하여 안정적으로 작동 한 유일한 제품이므로 감사합니다!
Dominic K

2
이것은 .each()루프를 사용하여 item요소 를 반복 하는 동안 나를 위해 일했습니다 $('dc\\:creator, creator', this).text(). 그래도 왜 여분 , creator이 필요한지 dc\\:creator잘 모르겠고 작동하지 않았습니다.
Fillip Peyton 2014

20

jquery 1.5를 사용하는 경우 노드 선택기 속성 값 주위에 따옴표를 추가해야 작동합니다.

.find('[nodeName="z:row"]')

19

위의 답변은 정확 해 보이지만 웹킷 브라우저 (Safari, Chrome)에서는 작동하지 않습니다. 더 나은 솔루션은 다음과 같습니다.

.find("[nodeName=z:myRow, myRow]")    

5
이것은 jQuery 버전 1.4.4에서 작동을 멈춘 것 같습니다. 이는 jQuery가 더 나은 XML 네임 스페이스 지원을 제공한다는 것을 의미합니다. 안전을 위해이 작동합니다$('[nodeName=rs:data],data')
Josh Pearce 2011 년

16

누군가가 jQuery없이 일반 자바 스크립트를 사용하고 Google 크롬 (웹킷)의 경우이를 수행해야하는 경우 많은 연구와 테스트 후에 이것이 작동하도록 찾은 유일한 방법입니다.

parentNode.getElementsByTagNameNS("*", "name");

다음 노드를 검색하는 데 작동합니다 <prefix:name>.. 보시다시피 접두사 또는 네임 스페이스가 생략되었으며 태그 이름이 인 경우 다른 네임 스페이스의 요소와 일치합니다 name. 그러나 이것이 당신에게 문제가되지 않기를 바랍니다.

이 중 어느 것도 나를 위해 일하지 않았습니다 (Google 크롬 확장 프로그램을 개발 중입니다).

getElementsByTagNameNS("prefix", "name")

getElementsByTagName("prefix:name")

getElementsByTagName("prefix\\:name")

getElementsByTagName("name")

편집 : 잠자기 후 작업 해결 방법을 찾았습니다. :)이 함수는 다음nodeName과 같은전체와일치하는 첫 번째 노드를 반환합니다<prefix:name>.

// Helper function for nodes names that include a prefix and a colon, such as "<yt:rating>"
function getElementByNodeName(parentNode, nodeName)
{   
    var colonIndex = nodeName.indexOf(":");
    var tag = nodeName.substr(colonIndex + 1);
    var nodes = parentNode.getElementsByTagNameNS("*", tag);
    for (var i = 0; i < nodes.length; i++)
    {
        if (nodes[i].nodeName == nodeName) return nodes[i]
    }
    return undefined;
}

일치하는 모든 요소를 ​​반환해야하는 경우 쉽게 수정할 수 있습니다. 도움이 되었기를 바랍니다.


14

위의 솔루션 중 어느 것도 잘 작동하지 않습니다. 나는 이것을 발견하고 속도가 향상되었습니다. 이것을 추가하고 매력처럼 작동했습니다.

$.fn.filterNode = function(name) {
    return this.find('*').filter(function() {
       return this.nodeName === name;
    });
};

용법:

var ineedthatelementwiththepsuedo = $('someparentelement').filterNode('dc:creator');

출처 : http://www.steveworkman.com/html5-2/javascript/2011/improving-javascript-xml-node-finding-performance-by-2000/


스 니펫 감사합니다. 이것은 매우 유용하고 문제를 해결합니다.
길만

9

"\\"이스케이프는 완전하고 간단하지 않습니다.

.find('[nodeName="z:row"]')

Jquery 1.7에서 메소드가 손상된 것 같습니다. 필터 함수를 사용하여 1.7에 대한 솔루션을 찾을 수있었습니다. 여기에서 Javascript XML Node Finding Performance 향상


3

jQuery 1.7부터 네임 스페이스 요소를 찾기위한 일부 해결 방법에 문제가 있다는 점에 주목할 가치가 있습니다. 자세한 내용은 다음 링크를 참조하십시오.


성능이 중요한 경우 최상의 솔루션은 jQuery없이 태그를 선택하는 것입니다. 비교는 다음을 참조하십시오. jsperf.com/node-vs-double-select/13

3

주석에서 찾은 솔루션 : jQuery $ (). find를 사용하여 네임 스페이스로 XML 구문 분석

콜론 뒤에 노드 이름의 두 번째 절반을 사용하면 나를 위해 일했습니다. 중고 .find ( "위도") 대신 .find ( "지리적 \ 위도") 그리고 그것은 나를 위해 일했습니다.


내 설정 :

  • 크롬 42
  • jQuery 2.1.3

샘플 XML (Google Contacts API의 스 니펫) :

<entry>
  <id>http://www.google.com/m8/feeds/contacts/mstefanow%40gmail.com/base/0</id>
  <gd:email rel="http://schemas.google.com/g/2005#other" address="email@example.com" primary="true"/>
</entry>

파싱 ​​코드 :

var xmlDoc = $.parseXML( xml );
var $xml = $( xmlDoc );
var $emailNode = $xml.find( "email" );
$("#email").html($emailNode.attr("address"));

Plnkr : http://plnkr.co/edit/l8VzyDq1NHtn5qC9zTjf?p=preview


도와 드릴 수있어서 다행입니다 :)
Mike Grace

2

jQuery 1.7은 다음에서 작동하지 않습니다.

$(xml).find("[nodeName=a:IndexField2]")

내가 크롬, 파이어 폭스 및 IE에서 작업하게 된 한 가지 해결책은 IE에서 작동하는 선택기와 Chrome에서 작동하는 선택기를 사용하는 것입니다. 한 가지 방법은 IE에서 작동하고 다른 하나는 Chrome에서 작동한다는 사실을 기반으로합니다.

$(xml).find('a\\\\:IndexField2, IndexField2')

IE에서는 네임 스페이스를 사용하는 노드를 반환하고 (Firefox 및 IE에는 네임 스페이스가 필요함) Chrome에서 선택기는 비 네임 스페이스 선택기를 기반으로 노드를 반환합니다. Safari에서 테스트하지는 않았지만 Chrome에서 작동하기 때문에 작동합니다.


2

내 솔루션 (Php 프록시를 사용하기 때문에)은 다음을 대체하는 것입니다 : namespace by _ ... 그래서 더 이상 네임 스페이스 문제가 없습니다 ;-)

간단하게!



2

2016 년 초부터 다음 구문이 jQuery 1.12.0에서 작동합니다.

  • IE 11 (11.0.9600.18204, 업데이트 11.0.28, KB3134815) : .find("z\\:row")
  • Firefox 44.0.2 : .find("z\\:row")
  • Chrome 44.0.2403.89m : .find("row")

구문 .find("[nodeName=z:row]")은 위에 언급 된 브라우저에서 작동하지 않습니다. Chrome에서 네임 스페이스를 적용 할 방법을 찾지 못했습니다.

모두 종합하면 위에서 언급 한 모든 브라우저에서 다음 구문이 작동합니다. .find("row,z\\:row")


1

위에서 언급했듯이 현재 브라우저 / 버전의 jQuery에는 위의 솔루션에 문제가 있습니다. 제안 된 플러그인은 대소 문자 문제로 인해 완전히 작동하지 않습니다 ( nodeName속성으로서 때때로 모두 대문자 임). 그래서 다음과 같은 빠른 기능을 작성했습니다.

$.findNS = function (o, nodeName)
{
    return o.children().filter(function ()
    {
        if (this.nodeName)
            return this.nodeName.toUpperCase() == nodeName.toUpperCase();
        else
            return false;
    });
};

사용 예 :

$.findNS($(xml), 'x:row');

jQuery 버전 문제를 고려할 때 이것은 분명히 최상의 솔루션입니다
MatteoSp



0

XML을 구문 분석하기 위해 JQuery를 사용하는 것에 대한 문서를 보지 못했습니다. JQuery는 일반적으로 브라우저 dom을 사용하여 HTML 문서를 탐색하지만 html 자체를 읽는다고 생각하지 않습니다.

JavaScript 자체에 내장 된 XML 처리를 살펴 봐야 할 것입니다.

http://www.webreference.com/programming/javascript/definitive2/


3
완전히 동의하지 않습니다. jQuery를 사용하면 응답 XML을 쉽게 처리 할 수 ​​있습니다. 문제는 xml 네임 스페이스를 사용하는 것뿐입니다.
Richard Clayton

1
@Richard : Ajax를 사용할 때 jQuery 는 실제로 XML 문서 인 responseXML내장 XMLHttpRequest객체 의 속성을 사용합니다 . 그러나 jQuery (1.5 parseXML가 도입 될 때까지 )에는 XML을 파싱 할 방법이 없었기 때문에 Chris가 옳았습니다.
Tim Down

0

네임 스페이스를 빈 문자열로 대체했습니다. 나를 위해 잘 작동합니다. 브라우저에서 테스트 된 솔루션 : Firefox, IE, Chrome

내 작업은 Sharepoint EXCEL REST API를 통해 EXCEL 파일을 읽고 구문 분석하는 것이 었습니다. XML 응답에는 "x :"네임 스페이스가있는 태그가 포함됩니다.

XML의 네임 스페이스를 빈 문자열로 바꾸기로 결정했습니다. 다음과 같이 작동합니다. 1. XML 응답에서 관심있는 노드를 가져옵니다. 2. 선택한 노드 XML 응답 (문서)을 문자열로 변환합니다. 2. 네임 스페이스를 빈 문자열로 바꿉니다. 3. 문자열을 다시 XML- 문서로 변환합니다.

여기에서 코드 개요보기->

function processXMLResponse)(xData)
{
  var xml = TOOLS.convertXMLToString("", "",$(xData).find("entry content")[0]);
  xml = xml.replace(/x:/g, "");            // replace all occurences of namespace
  xData =  TOOLS.createXMLDocument(xml);   // convert string back to XML
}

XML에서 문자열로 변환하려면 http://www.sencha.com/forum/showthread.php?34553-Convert-DOM-XML-Document-to-string 에서 솔루션을 찾으십시오.


0

또는 프로젝트에서 fast-xml-parser 를 사용 하고 XML 데이터를 JS / JSON 객체로 변환 할 수 있습니다 . 그런 다음이를 개체 속성으로 사용할 수 있습니다. JQuery 또는 다른 라이브러리를 사용하지 않지만 목적을 해결할 수 있습니다.

var xmlData = '<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">'
+'   <s:Schema id="RowsetSchema">'
+'     <s:ElementType name="row" content="eltOnly" rs:CommandTimeout="30">'
+'       <s:AttributeType name="ows_ID" rs:name="ID" rs:number="1">'
+'        <s:datatype dt:type="i4" dt:maxLength="4" />'
+'      </s:AttributeType>'
+'       <s:AttributeType name="ows_DocIcon" rs:name="Type" rs:number="2">'
+'        <s:datatype dt:type="string" dt:maxLength="512" />'
+'      </s:AttributeType>'
+'       <s:AttributeType name="ows_LinkTitle" rs:name="Title" rs:number="3">'
+'        <s:datatype dt:type="string" dt:maxLength="512" />'
+'      </s:AttributeType>'
+'       <s:AttributeType name="ows_ServiceCategory" rs:name="Service Category" rs:number="4">'
+'        <s:datatype dt:type="string" dt:maxLength="512" />'
+'      </s:AttributeType>'
+'    </s:ElementType>'
+'  </s:Schema>'
+'   <rs:data>'
+'    <z:row ows_ID="2" ows_LinkTitle="Sample Data 1" />'
+'    <z:row ows_ID="3" ows_LinkTitle="Sample Data 2" />'
+'    <z:row ows_ID="4" ows_LinkTitle="Sample Data 3" />'
+'  </rs:data>'
+'</xml>'

var jsObj = parser.parse(xmlData,{attrPrefix:"",ignoreTextNodeAttr: false});
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][0],null,4) + "<br>");
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][1],null,4) + "<br>");
document.write(JSON.stringify(jsObj.xml["rs:data"]["z:row"][2],null,4) + "<br>");
<script src="https://cdnjs.cloudflare.com/ajax/libs/fast-xml-parser/2.9.2/parser.min.js"></script>

js / json 객체로 구문 분석하는 동안 네임 스페이스를 무시할 수 있습니다. 이 경우으로 직접 액세스 할 수 있습니다 jsObj.xml.data.row.

for(var i=0; i< jsObj.xml.data.row.length; i++){
  console.log(jsObj.xml.data.row[i]);
}

면책 조항 : 저는 fast-xml-parser를 만들었습니다.


-1

Webkit 브라우저의 경우 콜론을 생략 할 수 있습니다. <media:content>예를 들어 RSS 피드에서 찾으 려면 다음을 수행 할 수 있습니다.

$(this).find("content");

최신 사파리에서는 사용을 지원하지 않습니다. 이전 버전에서만 작동합니다.
Baryon Lee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.