문제

JDOM을 사용하여 XML 파일로 읽은 다음 XPath를 사용하여 JDOM 문서에서 데이터를 추출하고 싶습니다. 문서 객체를 잘 만들지 만 XPath를 사용하여 요소 목록에 대한 문서를 쿼리 할 때 아무것도 얻지 못합니다.

내 XML 문서에는 루트 요소에 정의 된 기본 네임 스페이스가 있습니다. 재미있는 것은 기본 네임 스페이스를 제거하면 XPath 쿼리를 성공적으로 실행하고 원하는 요소를 반환하는 것입니다. XPath 쿼리를 결과를 반환하려면 다른 무엇을해야합니까?

XML :

<?xml version="1.0" encoding="UTF-8"?>
<collection xmlns="http://www.foo.com">
<dvd id="A">
  <title>Lord of the Rings: The Fellowship of the Ring</title>
  <length>178</length>
  <actor>Ian Holm</actor>
  <actor>Elijah Wood</actor>
  <actor>Ian McKellen</actor>
</dvd>
<dvd id="B">
  <title>The Matrix</title>
  <length>136</length>
  <actor>Keanu Reeves</actor>
  <actor>Laurence Fishburne</actor>
</dvd>
</collection>

자바:

public static void main(String args[]) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    Document d = builder.build("xpath.xml");
    XPath xpath = XPath.newInstance("collection/dvd");
    xpath.addNamespace(d.getRootElement().getNamespace());
    System.out.println(xpath.selectNodes(d));
}
도움이 되었습니까?

해결책

xpath 1.0 기본 네임 스페이스의 개념을 지원하지 않습니다 (xpath 2.0 하다). refix되지 않은 태그는 항상 이름이없는 네임 스페이스의 일부로 가정됩니다.

사용할 때 xpath 1.0 다음과 같은 것이 필요합니다.

public static void main(String args[]) throws Exception {
    SAXBuilder builder = new SAXBuilder();
    Document d = builder.build("xpath.xml");
    XPath xpath = XPath.newInstance("x:collection/x:dvd");
    xpath.addNamespace("x", d.getRootElement().getNamespaceURI());
    System.out.println(xpath.selectNodes(d));
}

다른 팁

나는 비슷한 문제가 있었지만, XML 입력이 혼합되어 있었는데, 그 중 일부에는 네임 스페이스가 정의되어 있고 다른 일부는 그렇지 않은 것이라는 것이 었습니다. 내 문제를 단순화하기 위해 문서를로드 한 후 다음 JDOM 스 니펫을 실행했습니다.

for (Element el : doc.getRootElement().getDescendants(new ElementFilter())) {
    if (el.getNamespace() != null) el.setNamespace(null);
}

모든 네임 스페이스를 제거한 후 간단하게 사용할 수있었습니다. getchild ( "elname") 스타일 탐색 또는 간단한 xpath 쿼리.

이 기술을 일반적인 솔루션으로 추천하지는 않지만 제 경우에는 확실히 유용했습니다.

다음을 수행 할 수도 있습니다

/*[local-name() = 'collection']/*[local-name() = 'dvd']/

여기 유용한 XPath 쿼리 목록입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top