2012-09-20 40 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); 
     } 
    } 

} 

STRUCT

下面是的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); 
     } 
    } 

} 

歐tput的

<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

在你的問題的標題CDATA參考是一種誤導。 XML中的CDATA部分是這樣寫的XML文件的一部分:

<![CDATA[ … ]]> 

該部分的內容不被解析爲XML,而是作爲原始字符的文本處理。因此,該部分中的每<是另一種編寫&lt;的替代方法。

CDATA不是XML信息集的一部分。大多數應用程序不會,也不應該關心輸入文本是寫成CDATA部分,還是「正常」文本或混合這兩種文本。只有在實際的序列化文件表示的非常低的層次上,你也可以處理諸如空白,縮進,字符編碼等等,CDATA是否重要。這就是你提到的例子:顯然有一種方法可以告訴JAXB一個給定的字符串應該被呈現爲一個CDATA節或者作爲具有字符引用的「普通」XML。

對於您的應用程序,這似乎沒什麼用處。爲了使用CDATA,您的輸入XML將已經必須包含CDATA標記。因爲它沒有(根據我們的例子),解析器別無選擇,只能將其視爲格式良好的XML。 answer by Blaise已經指出,您可能仍然能夠在數據結構中「按原樣」表示該子樹,無論是作爲DOM節點還是作爲XML字符串。