2009-05-08 2 views
5

나는 다음과 같은 XML 문서가 : 나는 SessionIndex의 내용을 좀하고 싶습니다Nokogiri는 내 네임 스페이스를 어떻게 이해합니까?

<samlp:LogoutRequest ID="123456789" Version="2.0" IssueInstant="200904051217"> 
    <saml:NameID>@[email protected]</saml:NameID> 
    <samlp:SessionIndex>abcdefg</samlp:SessionIndex> 
</samlp:LogoutRequest> 

을 그것에서 (즉, 'ABCDEFG'이다). 나는 이것을 시도했다 :

XPATH_QUERY = "LogoutRequest[@ID][@Version='2.0'][IssueInstant]/SessionIndex" 
SAML_XMLNS = 'urn:oasis:names:tc:SAML:2.0:assertion' 
SAMLP_XMLNS = 'urn:oasis:names:tc:SAML:2.0:protocol' 

require 'nokogiri' 
doc = Nokogiri::XML(xml) 
doc.xpath(XPATH_QUERY, 'saml' => SAML_XMLNS, 'samlp' => SAMLP_XMLNS) 

그러나 나는 다음과 같은 오류를 얻을 : 나는 XPath 쿼리에 네임 스페이스를 추가하려고했습니다

Nokogiri::XML::SyntaxError: Namespace prefix samlp on LogoutRequest is not defined 
Nokogiri::XML::SyntaxError: Namespace prefix saml on NameID is not defined 
Nokogiri::XML::SyntaxError: Namespace prefix samlp on SessionIndex is not defined 

,하지만 아무것도 변경되지 않습니다.

Nokogiri에게 네임 스페이스가 유효하다는 것을 왜 확신시킬 수 없습니까?

답변

6

이 문서의 네임 스페이스가 올바르게 선언 된 것처럼 보이지 않습니다. 루트 노드에 xmlns:samlpxmlns:saml 특성이 있어야합니다. 이런 경우, 노코 기리은 본질적으로 당신의 XPath를 작동 있도록 즉,

doc.xpath(XPATH_QUERY) 
+0

에 두 번째 인수로 제공합니다. 말 그대로 irb에서 제대로 작동하지만 내 사양을 실행하면 여전히 불어납니다. Garr. –

+0

알았습니다! Nokogiri는 발견 한 노드를 래핑하는 "오류"노드를 반환하지만 _really_did_find_the_node_! –

9

을 제거하면 내가 당신을 위해 두 가지 옵션을 참조하십시오 (이 URI에 또는 URN을에 매핑 할 수 없기 때문에) 네임 스페이스를 무시합니다 :

  1. 그 일의

    http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document#remove_namespaces%21-instance_method

    브 루트 포스 방법은 모든 네임 스페이스를 제거합니다. 네임 스페이스 충돌이있는 곳에 문제가 생길 수 있습니다.

  2. 사용

    http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document#collect_namespaces-instance_method

    훨씬 더 나은 솔루션을 collect_namespaces. 네임 스페이스 (예 : irb)를 식별하고이를 하드 코드 할 때 이것을 한 번 사용할 수 있습니다.

    또는

    런타임에 그것을 사용하고, 나에게 같은 오류 ... 어떤 상황을 줄 것으로 보인다 http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Node#xpath-instance_method

+0

'collect_namespaces'는 알아야 할 좋은 것입니다. – mikezter

관련 문제