【问题标题】:Model a class from a string of Html, instantiate the class and populate variables from the string, and return the html string from the class [closed]从 Html 字符串建模一个类,实例化该类并从该字符串填充变量,并从该类返回 html 字符串 [关闭]
【发布时间】:2014-11-09 22:17:26
【问题描述】:

这可能有点难以解释,但我正在尝试从一串 html 标记创建 Java 类。我希望能够获取字符串并创建一个对象并用这些值填充所有成员变量。从那里我还希望能够获取该对象并让它吐回 html 标记。 html 标记在技术上是 XML,所以我必须认为这是可能的。这是 html 字符串的快速 sn-p - 它相当简单。有一个带有 0 到多个区域标签的地图标签作为子标签。

<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 库吗?我在挣扎。

【问题讨论】:

  • 您是否需要在 Java 中解析 XML 的库?如果是这样,一个快速的谷歌搜索会告诉你大量的选择。
  • 是的,我知道,我以前使用过这些库。我想我只是在寻找一个更适合 XML 的库,实际上是 Html。我不知道对我来说只是感觉有点不同。
  • “实际上是 HTML 的 XML”。它是否有效的 XML?如果是这样,请使用 XML 库。
  • 它是有效的 XML。对不起,我不是故意提出一个愚蠢的问题,老实说,否决票是不必要的。我没有太多在 Java 中使用 XML 的经验,所以一直在寻找一些指针。
  • 我没有对你投反对票,但可能因为你的问题过于宽泛而投反对票的人。

标签: java html xml jaxb xsd


【解决方案1】:

我会结合使用JTidyJAXBXStream

JTidy 将帮助您清除不需要有效 XHTML 的 HTML 标记。

然后可以使用 JAXB 或 XStream 将 XHTML 解组为 Java 对象并将它们编组回 XML 表单。

可以说,我更熟悉 JAXB,所以我将概述 JAXB 的方式。

使用 JAXB,您可以获取 XHTML 的一些 XML Schema,例如 XHTML 1.0 Strict Schema,然后使用 JAXB 的架构编译器 XJC 对其进行编译。

由于一些命名冲突,编译很可能从一开始就不会成功。例如,xml:langlang 属性将映射到 Java 类中的相同 lang 属性。此时,您需要使用 binding file 来自定义 XML Schema -> Java 派生。

这是上面提到的架构的样子:

<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>

当您(希望)最终成功时,您将获得一个包含大约 90 多个 Java 类的包,这些 Java 类派生自 XHTML 1.0 Strict XML Schema。您将获得像 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();

现在您有了自己的 mapareas,可以在 Java 级别上对它们做任何您想做的事情。

最后,您可以将您的 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);

所以或多或少是这样的。

(上面的两个代码sn-ps都只是草图,没有经过测试。)


现在是一个小警告。 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 Strict 模式时可以使用的绑定文件:

这与我在上面作为代码 sn-p 发布的绑定文件基本相同。

审稿人注意:在这个答案中,我确实参考了我自己的项目。但是,如果 OP 选择使用 JAXB,我所指的模块和代码与问题非常匹配。

【讨论】:

    猜你喜欢
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多