2015-01-14 3 views
0

인터넷에서이 기능을 구현하는 방법에 대한 많은 예제를 찾고 있습니다. 그러나이 중 어떤 것도 제 경우에는 작동하지 않습니다. XML 데이터가 포함 된 문자열이 있고 결과의 XPath가 어떻게 표시되는지 알고 있습니다. 내가 읽을 수 있어야하고, 예를 들어Java를 사용하여 XML 문서 업데이트

<?xml version="1.0"?> 
    <m:parent xmlns:m="http://www.somescheme"> 
     <doc:header xmlns:doc="http://www.somescheme"> 
     <doc:documentId>137</doc:documentId> 
     <doc:documentDescription>Some Description</doc:documentDescription> 
     <doc:task> 
      <doc:id>49</doc:id> 
      <doc:name>Some Name</doc:name> 
      <doc:description>Some Task Description</doc:description> 
      <doc:outcome/> 
      <doc:dueDate/> 
      <doc:priority>50</doc:priority> 
      </doc:task> 
     </doc:header> 
     <m:otherinfo>234324</m:otherInfo> 
     </m:parent> 

말은 내가 액세스하고 XPath를 otherInfo 업데이트 될 ': 부모/m otherInfo m'할 필요가 : 나는 XML 구조는 다음과 같이 찾고 있습니다 예를 들어 말 세트. doc의 경우 : 결과는 'm : parent/doc : header/doc : task/doc : outcome'입니다. 이것은 런타임에 설정해야하는 값입니다.

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
     new InputSource("data.xml")); 

    XPath xpath = XPathFactory.newInstance().newXPath(); 
    NodeList nodes = (NodeList) xpath.evaluate("//m:parent/doc:header/doc:task/doc:outcome", doc, 
     XPathConstants.NODESET); 

코드 그러나 나는 결과를 얻고 있지 않다,

당신이 내가 놓친 거지 무엇을 지적 할 수 위의 같은 것을해야 하는가? 당신이 네임 스페이스와 XPATH 식을 평가하기 전에

친절 감사 최대

+1

"결과를 얻지 못했습니다"를 정의하십시오. – kosa

+0

스키마가 많은'doc : header' 엘리먼트를 허용 할 가능성을 고려하십시오. – gknicker

+0

정의 : NodeList를 표현식의 결과로 가져 오지 못합니다. 따라서 목록의 가능한 노드를 반복 처리 할 수없고 @gknicker 사실 일 수 있습니다. getattribute 나 요소를 사용하여 값을 얻었을 때 응답을 얻었을 때, 첫 번째 값만 올바른 값임을 나타낼 수는 없었습니다. – maxhamulyak

답변

0

두 가지 추가 작업을 수행해야합니다.

  1. DocumentBuilderFactory 인스턴스는 기본적으로 네임 스페이스를 인식하지 않습니다. 그래서 setNamespaceAware(true)으로 전화해야합니다.
  2. NamespaceContext 인터페이스를 직접 구현하여 XPath 인스턴스에 전달하십시오.

여기에서 간단한 NamespaceContext 구현은 정적 내부 클래스입니다. 여기서 getNamespaceURI() 메서드 만 구현됩니다.

static class MyNamespaceContext implements NamespaceContext { 
    @Override 
    public String getNamespaceURI(String prefix) { 
    if(prefix == null) { 
     throw new IllegalArgumentException(); 
    } else if(prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) { 
     return XMLConstants.NULL_NS_URI; 
    } else if(prefix.equals(XMLConstants.XML_NS_PREFIX)) { 
     return XMLConstants.XML_NS_URI; 
    } else if(prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) { 
     return XMLConstants.XMLNS_ATTRIBUTE_NS_URI; 
    } else if(prefix.equals("m")) { 
     return "http://www.somescheme"; 
    } else if(prefix.equals("doc")) { 
     return "http://www.somescheme"; 
    } else { 
     return XMLConstants.NULL_NS_URI; 
    } 
    } 

    @Override 
    public String getPrefix(String namespaceURI) { 
    throw new UnsupportedOperationException(); 
    } 

    @Override 
    public Iterator getPrefixes(String namespaceURI) { 
    throw new UnsupportedOperationException(); 
    } 
} 

여기 DocumentBuilderFactory와 부분 : 두 개의 네임 스페이스 접두사가 실제로 같은 네임 스페이스 URI에 연결되어

DocumentBuilderFactory documentBuilderFactory = 
    DocumentBuilderFactory.newInstance(); 
documentBuilderFactory.setNamespaceAware(true); 
Document doc = documentBuilderFactory.newDocumentBuilder().parse(
    new InputSource("data.xml")); 

XPath xpath = XPathFactory.newInstance().newXPath(); 
xpath.setNamespaceContext(new MyNamespaceContext()); 
NodeList nodes = (NodeList) xpath.evaluate(
    "//m:parent/doc:header/doc:task/doc:outcome", doc, 
    XPathConstants.NODESET); 

: (Using the Java language NamespaceContext object with XPath자세한 내용과 다른 구현이 IBM developerWorks 기사 참조) . 실제로는 "//doc:parent/doc:header/doc:task/doc:outcome"과 같이 XPATH 표현식에서 하나의 접두사 만 사용할 수 있으며 두 가지를 모두 구현할 때도 필요하지 않습니다. NamespaceContext 구현.

+0

고맙습니다, 제 문제가 수정되었습니다. // m : parent/doc : header/doc : task/doc : 결과는 이제 작동합니다. – maxhamulyak

관련 문제