2012-09-20 5 views
2

xml 파일을 구문 분석해야합니다 (JAXB를 사용하여 구문 분석합니다).하지만 XML 파일 값의 일부를 문자열로 가져 오려고합니다. 내가 인터넷에서 서핑을 한 후에는 CDATA를 사용하여 가능할 수 있습니다. 다음 링크에서는 CDATA에 대해 이야기합니다. 하지만 코드에 의심의 여지가 있습니다. 어디서 어떻게 CDATA로 취급하고 싶은 요소를 지정해야합니까?JAXB에서 CDATA 처리

http://jaxb.java.net/faq/JaxbCDATASample.java

내 XML은 다음처럼 보인다.

<root> 
    <Service>CDATASERVICE</Service> 
    <Child> 
     <param> 
      <value> 
       <struct> 
        <member> 
         <name>Servicename</name> 
         <value>service1</value> 
        </member> 
       </struct> 
      </value> 
     </param> 
     <param> 
      <value> 
       <struct> 
        <member> 
         <name>item1</name> 
         <value>36</value> 
        </member> 
        <member> 
         <name>Cdata</name> 
         <value> 
          <struct> 
           <member> 
            <name>services</name> 
            <value> 
             <array> 
              <data> 
               <value>ABCD</value> 
              </data> 
             </array> 
            </value> 
           </member> 
          </struct> 
         </value> 
        </member> 
        <member> 
         <name>item2</name> 
         <value> 
          <int>10</int> 
         </value> 
        </member> 
       </struct> 
      </value> 
     </param> 
    </Child> 
</root> 

위의 XML 파일에서 다음 부분을 가져 오려면 어떻게해야합니까?

    <name>Cdata</name> 
          <value> 
           <struct> 
            <member> 
             <name>services</name> 
             <value> 
              <array> 
               <data> 
                <value>ABCD</value> 
               </data> 
              </array> 
             </value> 
            </member> 
           </struct> 
          </value> 
+0

이것은 CDATA를 포장하는 방법입니다. http://www.w3schools.com/xml/xml_cdata.asp – popfalushi

답변

1

이 사용 사례에 대해 지정된 DomHandler@XmlAnyElement를 사용할 수 있습니다.

MemberHandler

@XmlAnyElement 주석은 XML과 같은 XML 문서의 일부를 유지할 수 있습니다. 기본적으로 이는 DOM 노드로 유지됩니다. DomHandler을 구현하면 String과 같은 대체 표현을 활용할 수 있습니다. 다음은 구조체

package forum12512299; 

import java.io.*; 
import javax.xml.bind.ValidationEventHandler; 
import javax.xml.bind.annotation.DomHandler; 
import javax.xml.transform.Source; 
import javax.xml.transform.stream.*; 

public class MemberHandler implements DomHandler<String, StreamResult> { 

    private static final String MEMBER_START_TAG = "<member>"; 
    private static final String MEMBER_END_TAG = "</member>"; 

    private StringWriter xmlWriter; 

    public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) { 
     xmlWriter = new StringWriter(); 
     return new StreamResult(xmlWriter); 
    } 

    public String getElement(StreamResult rt) { 
     String xml = rt.getWriter().toString(); 
     int beginIndex = xml.indexOf(MEMBER_START_TAG) + MEMBER_START_TAG.length(); 
     int endIndex = xml.indexOf(MEMBER_END_TAG); 
     return xml.substring(beginIndex, endIndex); 
    } 

    public Source marshal(String n, ValidationEventHandler errorHandler) { 
     try { 
      String xml = MEMBER_START_TAG + n.trim() + MEMBER_END_TAG; 
      StringReader xmlReader = new StringReader(xml); 
      return new StreamSource(xmlReader); 
     } catch(Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

} 

DomHandler@XmlAnyElement 매핑에서 참조하는 방법의 예입니다.

package forum12512299; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
public class Struct { 

    private List<String> members; 

    @XmlAnyElement(MemberHandler.class) 
    public List<String> getMembers() { 
     return members; 
    } 

    public void setMembers(List<String> members) { 
     this.members = members; 
    } 

} 

input.xml

나는 흥미로운 부분에 XML 문서 아래로 단순화했습니다 아래 :

<struct> 
    <member> 
     <name>item1</name> 
     <value>36</value> 
    </member> 
    <member> 
     <name>Cdata</name> 
     <value> 
      <struct> 
       <member> 
        <name>services</name> 
        <value> 
         <array> 
          <data> 
           <value>ABCD</value> 
          </data> 
         </array> 
        </value> 
       </member> 
      </struct> 
     </value> 
    </member> 
    <member> 
     <name>item2</name> 
     <value> 
      <int>10</int> 
     </value> 
    </member> 
</struct> 

데모

package forum12512299; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Struct.class); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum12512299/input.xml"); 
     Struct struct = (Struct) unmarshaller.unmarshal(xml); 

     for(String string : struct.getMembers()) { 
      System.out.println(string); 
     } 
    } 

} 

오우

<name>item1</name><value>36</value> 

<name>Cdata</name><value><struct><member><name>services</name><value><array><data><value>ABCD</value> 
          </data> 
         </array> 
        </value> 

<name>item2</name><value><int>10</int> 
     </value> 
0

tput을 질문의 제목에서 CDATA에 대한 언급은 잘못된 것입니다.

<![CDATA[ … ]]> 

해당 섹션의 내용은 XML로 구문 분석, 대신 원시 문자 텍스트로 처리되지 않습니다 XML에서 CDATA 섹션은 다음과 같이 기록 된 XML 파일의 일부이다. 따라서 해당 부분에 <에 대해 &lt;을 쓰는 대신 사용할 수 있습니다.

CDATA는 XML 정보 집합의 일부가 아닙니다. 대부분의 응용 프로그램은 입력 텍스트가 CDATA 섹션으로 작성되었는지, "정상적인"텍스트로 작성되었는지, 또는이 두 가지가 혼합되어 있는지에 상관하지 않습니다. 공백, 들여 쓰기, 코드 작성기 인코딩 등을 다루는 실제 직렬화 된 파일 표현의 아주 낮은 레벨에서만 CDATA가 중요합니다. 그것은 당신이 참조한 예제입니다 : 주어진 문자열을 CDATA 섹션이나 문자 참조가있는 "일반"XML로 렌더링해야한다고 JAXB에 알리는 방법이 있습니다.

응용 프로그램의 경우 거의 사용되지 않습니다. CDATA를 사용하려면 입력 XML에 이 이미에 CDATA 마크 업을 포함해야합니다. (우리의 예에 따르면) 파서는 올바른 형식의 XML로 취급 할 수 밖에 없습니다. answer by Blaise은 이미 데이터 구조 내에서 해당 하위 트리를 DOM 노드 또는 XML 문자열로 표현할 수있는 방법을 이미 지적했습니다.