2014-11-06 64 views
0

這可能有點難以解釋,但我試圖從類中創建一個Java類一串html標記。我希望能夠接受字符串並創建一個對象,並用值填充所有成員變量。從那裏我也希望能夠接受這個對象,並讓它吐出html標記。 html標記在技術上是XML,所以我必須認爲這是可能的。這是一個html字符串的快速片段 - 它非常簡單。有一個地圖標籤,其中0到多個地區標籤爲兒童。從Html的字符串中建立一個類,實例化類並從字符串中填充變量,並從類中返回html字符串

<map id="..." name="..."> 
<area shape="rect" alt="" title="" coords="68,67,159,159" href="/" target="_self" /> 
<area shape="circle" alt="" title="" coords="217,43,344,148" href="google.com" target="" /> 
.... 
</map> 

任何人都知道任何java庫來緩解這個過程?我正在掙扎。

+1

您是否要求使用Java解析XML的庫?如果是這樣,一個快速的谷歌搜索會顯示你很多選項。 – thatidiotguy 2014-11-06 21:06:08

+0

是的,我知道,我以前使用過這些庫。我想我只是在尋找一個更適合XML的lib,它實際上是Html。我不知道對我來說有點不同。 – 2014-11-06 21:12:56

+2

「XML實際上是HTML」。它是否有效的XML?如果是這樣,請使用XML庫。 – thatidiotguy 2014-11-06 21:15:16

回答

1

我會用JTidyJAXBXStream的組合來解決這個問題。

JTidy將幫助您清理不需要有效的XHTML的HTML標記。

然後可以使用JAXB或XStream將XHTML解組爲Java對象並將它們封送回XML Form。

我可以這麼說,更熟悉與JAXB,所以我將草繪JAXB的方式。

使用JAXB,您需要使用一些XHTML的XML模式,例如XHTML 1.0 Strict Schema,並使用JAXB的模式編譯器XJC進行編譯。

編譯很可能不會從一開始就成功,因爲有一些命名衝突。例如,xml:langlang屬性將映射到Java類中相同的lang屬性。此時,您需要使用binding file來自定義XML架構 - > Java派生。

下面是它如何可能看起來像在架構之上mentined:

<jaxb:bindings version="1.0" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" 
    jaxb:extensionBindingPrefixes="xjc"> 

    <jaxb:bindings schemaLocation="http://www.w3.org/2002/08/xhtml/xhtml1-strict.xsd" node="/xs:schema"> 
     <jaxb:schemaBindings> 
      <jaxb:package name="org.hisrc.w3c.xhtml.v_1_0_strict"/> 
     </jaxb:schemaBindings> 

     <jaxb:bindings node="xs:attributeGroup[@name='i18n']/xs:attribute[@ref='xml:lang']"> 
      <jaxb:property name="xmlLang"/> 
     </jaxb:bindings> 
     <jaxb:bindings node="xs:element[@name='bdo']/xs:complexType/xs:complexContent/xs:extension/xs:attribute[@ref='xml:lang']"> 
      <jaxb:property name="xmlLang"/> 
     </jaxb:bindings> 
    </jaxb:bindings> 

</jaxb:bindings> 

當你(希望)終於成功了,你會得到一個包,從XHTML 1.0導出一些90+的Java類嚴格的XML模式。您將獲得像MapArea這樣的類,併爲您的模式中的所有元素和屬性提供屬性。

有了這些類,您現在可以解組XML(理想情況下使用JTidy預處理)。這看起來像:

JAXBContext context = JAXBContext.newInstance("org.hisrc.w3c.xhtml.v_1_0_strict"); 
Unmarshaller unmarshaller = context.createUnmarshaller(); 
JAXBElement<Map> mapElement = (JAXBElement<Map>) unmarshaller.unmarshal(source); 
Map map = mapElement.getValue(); 
List<Area> areas = map.getArea(); 

現在,你有你的maparea S和做任何你想要與他們在Java級別。

最後,你可以marhsal你map回一些結果:

Marshaller marshaller = context.createMarshaller(); 
JAXBElement<Map> mapElement = new JAXBElement<Map>(
    new QName("http://www.w3.org/1999/xhtml", "map"), 
    Map.class, map); 
marshaller.marshal(mapElement, result); 

所以這是它或多或少。

(上述兩種代碼段只是草圖和未測試。)


查閱一個小警告。對於強結構化模式,JAXB是一個非常好的工具。XHTML屬於「半結構化」範疇,因爲它允許大量的混合內容,任意順序的元素等等。這些在JAXB架構派生類中有時看起來很醜陋的東西。例如,你會得到一個屬性,如:

@XmlElementRefs({ 
    @XmlElementRef(name = "object", namespace = "http://www.w3.org/1999/xhtml", type = org.hisrc.w3c.xhtml.v_1_0_strict.Object.class, required = false), 
    @XmlElementRef(name = "label", namespace = "http://www.w3.org/1999/xhtml", type = Label.class, required = false), 
    // 28 lines skipped 
    @XmlElementRef(name = "strong", namespace = "http://www.w3.org/1999/xhtml", type = Strong.class, required = false), 
    @XmlElementRef(name = "abbr", namespace = "http://www.w3.org/1999/xhtml", type = Abbr.class, required = false) 
}) 
@XmlMixed 
protected List<java.lang.Object> content; 

這不是很好。因此,JAXB可能有些不理想的任務


最後,小廣告塊

免責聲明:我領導一個名爲w3c-schemas的小型開源項目。該項目使用JAXB編譯一些W3C模式(例如,本身爲XLinkXML Schema)。該項目的目標是提供從這些模式編譯的即用型模式派生類 - 或可用於編譯的綁定文件。

所以當回答你的問題時,我剛剛添加了XHTML 1.0 Strict到我的項目。您可以訪問這裏的相關模塊:

下面是綁定文件編寫你自己的XHTML 1.0嚴格的模式時,你可以使用:

這基本上是我發佈爲上面代碼片段的相同綁定文件。

給評論者的筆記:在這個答案中,我指的是我自己的項目。但是,如果OP選擇使用JAXB,那麼我提到的模塊和代碼就非常適合這個問題。