2011-11-05 1 views
1

현재 JS 및 포함 된 XPath로 arround를 재생하고 있습니다. 나는 약간의 테스트 스크립트를 만들려고 노력 중이며 흥미로운 오류를 발견했다. 다음과 같이 evaluate 함수를 호출합니다.XPath/Javascript - 새 노드 트리를 만들 때 INVALID_STATE_ERR

var result = document.evaluate(
    xpath, 
    document, 
    null, 
    XPathResult.ANY_TYPE); 

이 경우 결과가 서로 다릅니다. 문자열, 부울 및 숫자 형식은 문제가 없지만 UNORDERED_NODE_ITERATOR_TYPE은 다소 까다 롭습니다.

function nodes(iterator, parentNode) { 
     var cur = iterator.iterateNext(); // do not touch! altering this object causes a INVALID_STATE_ERR Exception 
     var myObj = cur == null || cur == undefined ? undefined : cur.cloneNode(true); 
     var count = 0; 

     while(myObj) { 
      parentNode.appendChild(myObj); 
      var = iterator.iterateNext().cloneNode(true); 
     } 
    } 

을하지만이 기능을 실행하려고하면 나는 INVALID_STATE_ERR 예외를 얻을 : 결과를 처리 할 수 ​​

내 함수는 것 같습니다. 하지만 왜? 개체를 복제하고 부모 노드는 새로 만든 요소 노드입니다. 마지막에 원래의 본문 노드를 대체해야하는 document.createElement ('body')

new-body 요소를 다른 방식으로 만들어야합니까?이 예외는 새 본문 요소가 첨부되어 있기 때문에 발생합니까? 현재 문서 트리? createElement를 사용할 수없는 경우 어떻게해야합니까?

+0

http://jsfiddle.net/과 같은 사이트를 사용하여 문제를 재현 할 수 있도록 충분한 샘플 코드를 게시 해보십시오. 나는 var = iterator.iterateNext() .cloneNode (true);와 같은 줄이 구문 적으로 올바르지 않다고 두려워한다. XPath DOM API의 경우 먼저 배열에서 발견 된 노드를 수집 한 다음 DOM 트리를 조작하기 위해 결과를 반복 실행하는 것이 좋습니다. 반면에 HTML 문서는 정확히 하나의'body' 엘리먼트를 가지고있다. 그래서 왜 iterator를 사용해야 할까? 단일 노드 만 선택하면 안됩니까? –

+2

문제를 재현하기 위해 스 니펫을 테스트 케이스로 변형하려고 시도했습니다. http://jsfiddle.net/pe95g/2/. 나는 그 예제가 잘 동작해야한다고 생각한다. Mozilla와 Opera에서는 실제로 그렇게되지만 Chrome과 Safari에서는 "INVALID_STATE_ERR : DOM Exception 11"이 발생한다. DOM Level 3 XPath는 "반복을 무효화하는" "문서 수정"이 무엇인지 구체적으로 자세히 설명하지는 않았지만 WebKit의 DOM 구현 버그입니다. 스냅 샷 (http://jsfiddle.net/WT5Uk/1/)을 사용하도록 코드를 변경하면 Mozilla, Opera, Safari, Chrome에서 잘 작동합니다. –

+0

당신 말이 맞아요. 또한 스냅 샷으로 시도했지만 다른 이상한 실패를 발견했습니다. evaluate 함수를 사용할 때 "evaluate (xpathExpression, contextNode, namespaceResolver, resultType, result);"함수를 사용합니다. firefox에서는 같은 호출 스타일로 인해 chrome에서 오류가 발생합니다 (15.0.874.106). 거기서 나는 이렇게 부르셔야합니다 : "document.evaluate (xpath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE)"이상하게! 하지만 위와 똑같은 코드를 Firefox 7에서 실행할 수 있습니다. (답을 귀하의 코멘트로 추가하면 나에게 도움이되기 때문에 받아 들일 것입니다) – schlingel

답변

1

문제를 재현하기 위해 테스트 케이스를 만들려고했습니다 : http://jsfiddle.net/pe95g/2/. Mozilla와 Opera에서는 잘 작동하지만 Chrome과 같은 WebKit 브라우저에서는 실패합니다. 및 사파리. 내 견해로는 쿼리되는 DOM 문서가 변경되지 않아야합니다. XPath 반복이 발생하는 동안 해당 문서에 첨부되지 않은 노드 만 만들어지고 변경됩니다. 반면 W3C DOM Level 3 XPath 참고 "문서 수정"이 무엇인지에 대해서는 그다지 정확하지 않습니다. "반복을 무효화". 해결 방법으로

내가 대신 DOM 레벨 3의 XPath API, http://jsfiddle.net/WT5Uk/1/와 반복자의 스냅 샷을 사용하려고, 그 접근 방식은 document.evaluate (즉, 모질라, 오페라, 사파리, 크롬을 지원하는 모든 네 개의 주요 데스크톱 브라우저와 나를 위해 잘 작동). 이것이 제가 제안 할 수있는 유일한 해결책입니다.

관련 문제