我會用JTidy和JAXB或XStream的組合來解決這個問題。
JTidy將幫助您清理不需要有效的XHTML的HTML標記。
然後可以使用JAXB或XStream將XHTML解組爲Java對象並將它們封送回XML Form。
我可以這麼說,更熟悉與JAXB,所以我將草繪JAXB的方式。
使用JAXB,您需要使用一些XHTML的XML模式,例如XHTML 1.0 Strict Schema,並使用JAXB的模式編譯器XJC進行編譯。
編譯很可能不會從一開始就成功,因爲有一些命名衝突。例如,xml:lang
和lang
屬性將映射到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模式。您將獲得像Map
和Area
這樣的類,併爲您的模式中的所有元素和屬性提供屬性。
有了這些類,您現在可以解組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();
現在,你有你的map
和area
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模式(例如,本身爲XLink或XML Schema)。該項目的目標是提供從這些模式編譯的即用型模式派生類 - 或可用於編譯的綁定文件。
所以當回答你的問題時,我剛剛添加了XHTML 1.0 Strict到我的項目。您可以訪問這裏的相關模塊:
下面是綁定文件編寫你自己的XHTML 1.0嚴格的模式時,你可以使用:
這基本上是我發佈爲上面代碼片段的相同綁定文件。
給評論者的筆記:在這個答案中,我指的是我自己的項目。但是,如果OP選擇使用JAXB,那麼我提到的模塊和代碼就非常適合這個問題。
您是否要求使用Java解析XML的庫?如果是這樣,一個快速的谷歌搜索會顯示你很多選項。 – thatidiotguy 2014-11-06 21:06:08
是的,我知道,我以前使用過這些庫。我想我只是在尋找一個更適合XML的lib,它實際上是Html。我不知道對我來說有點不同。 – 2014-11-06 21:12:56
「XML實際上是HTML」。它是否有效的XML?如果是這樣,請使用XML庫。 – thatidiotguy 2014-11-06 21:15:16