2017-03-14 10 views
0

xdmNode를 dom 노드로 변환하고 싶습니다. createEventCountsTestDocument는 다음과 같은 XML을 기반으로 문서 생성색슨 : xdmNode를 org.w3c.dom.Node로 변환하십시오.

Processor proc = new Processor(false); 
XPathCompiler xpath = proc.newXPathCompiler(); 
Document doc = DocumentUtilities.createEventCountsTestDocument(); 
XdmNode xdmNode = proc.newDocumentBuilder().wrap(doc); 

expression = "/caseFileModel/EventCount/EventCountEvents[EventCmmnId=\"_4cd9cdaabbd244548a32afcd4cf2e1c0\" and EventEventType=\"CREATE\"]/Timestamps/Date[last()]"; 
value = xpath.evaluate(expression, xdmNode); 
XdmNode node = (XdmNode) value; 
Node element = ((Node) node.getExternalNode()); 
System.out.println(element.getTextContent()); 

:

<caseFileModel> 
     </EventCountEvents> 
     <EventCountEvents> 
      <EventCmmnId>_8dbe1b3fa1a04787b2ef35d153d93ae5</EventCmmnId> 
      <EventEventType>CREATE</EventEventType> 
      <EventCount>1</EventCount> 
      <Timestamps> 
       <Date>2017-03-13T16:47:04Z</Date> 
      </Timestamps> 
     </EventCountEvents> 
     <EventCountEvents> 
      <EventCmmnId>_4cd9cdaabbd244548a32afcd4cf2e1c0</EventCmmnId> 
      <EventEventType>CREATE</EventEventType> 
      <EventCount>1</EventCount> 
      <Timestamps> 
       <Date>2017-03-13T16:47:04Z</Date> 
      </Timestamps> 
     </EventCountEvents> 
    </EventCount> 
</caseFileModel> 

내가 올바른 출력, 즉 2017-03-03T12:00:00Z 그러나 elementcom.sun.org.apache.xerces.internal.dom.DeferredElementImpl 아닌 w3c.dom.Node입니다 얻을 나는 다음과 같은 부분적인 해결책을 발견했다. 즉, element.getNodeValue()으로 전화하면 null을 반환합니다. element.getFirstChild().getNodeValue()으로 전화하면 정확한 값 2017-03-03T12:00:00Z가 반환됩니다. 그래서 뭔가 잘못된 것으로 보이지만 그것을 찾을 수 없습니다. xdmNodew3c.dom.Node으로 변환하고 DeferredElementImpl으로 변환하는 방법을 찾고 싶습니다.

+1

문제가 무엇인지 이해하지 못합니다. DOM https://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-F68D080은 요소 노드의 노드 값을 다음과 같이 정의합니다. 올바른 결과를 얻으려면 null이되어야합니다. 'Node'는'com.sun.org.apache.xerces.internal.dom.DeferredElementImpl'에 의해 구현 된 인터페이스입니다. 원하는 결과가 어떤 것인지 잘 모르겠습니다. 클래스 기반 객체 모델을 원한다면 Java 세계에서 JDOM 또는 XOM을 사용하십시오. DOM은 정의에 따라 클래스가 구현할 인터페이스를 제공합니다. –

답변

1

몇 가지 사항이 있습니다. 꽤 복잡한 이야기 ​​인 것 같습니다.

Saxon에는 상위 인터페이스 인 XdmNode과 하위 인터페이스 인 NodeInfo의 두 가지 인터페이스 노드가 있습니다. XdmNode은 항상 NodeInfo의 래퍼입니다.

NodeInfo에는 상당히 많은 구현이 있습니다. Saxon에는 각각 TinyTree와 LinkedTree 모델을위한 두 가지 "기본"구현이 있습니다. DOM, JDOM, DOM4J, XOM 및 AXIOM을 포함한 외부 노드 모델을 래핑하는 구현도 있습니다. 당신이 시작하는 XdmNode 자체가 DOM Node을 감싸는 NodeInfo의 래퍼 인 경우

, 당신은 XdmNode.getExternalNode()를 사용하여 기본 DOM 노드를 얻을 수 있습니다. 이 메소드의 서명은 Object을 반환합니다. 래핑 된 노드가 DOM이거나 JDOM, XOM 또는 기타 일 수 있기 때문입니다.

위의 단락은 현재 수행중인 작업을 설명합니다. 결과가 com.sun.org.apache.xerces.internal.dom.DeferredElementImpl의 인스턴스라는 점에 대해 걱정할 필요가 없습니다. 이는 org.w3c.dom.Node 인터페이스를 구현하는 많은 내부 클래스 중 하나 일뿐입니다. ,

  1. 당신은 NodeOverNodeInfo 클래스의 인스턴스에 기본 NodeInfo을 포장 할 수 있습니다 당신이 시작하고있는 XdmNode는 DOM Node 래퍼가 아닌 경우

    는 다음 두 가지 옵션이 있습니다 기본 NodeInfo 노드의 DOM보기를 제공합니다. 그러나 Saxon 노드 (일반적으로)는 불변이므로 읽기 전용보기입니다.

  2. Saxon 노드를 ID 노드로 복사 할 수 있습니다. 이는 ID 변환을 사용하는 것이 가장 좋습니다.

DOM 트리를 처리 할 때 Saxon은 일반적으로 자체 내부 트리 모델을 처리 할 때보 다 5 배 더 느리다는 것을 알고 있어야합니다. 이것의 대부분은 이름과 네임 스페이스가 DOM에서 처리되는 비효율적 인 방법 때문입니다.

또한, 당신이 발견 한 것처럼, element.getNodeValue()와 같은 것들에 대한 DOM 메소드는 항상 여러분이 기대하는 것을 수행하지 않습니다. 개인적으로 전염병과 같은 DOM을 피합니다.