【问题标题】:How to generate xml file with an existing dtd for sample of data using Java如何使用 Java 为数据样本生成具有现有 dtd 的 xml 文件
【发布时间】:2020-07-30 00:18:14
【问题描述】:

我有一些数据存储在:

HashMap<Position, Double> listOfPoints = new HashMap<>();

其中 key 包含对 (x,y)。

我还定义了名为 generate.dtd 的 dtd 文件,其中包含我的结构:

<!ELEMENT table (point*,id,position,x,y,value)>
<!ELEMENT point (id,position,value)>
<!ELEMENT id (ID)>
<!ELEMENT position (x,y)>
<!ELEMENT value (#PCDATA)>
<!ELEMENT x (#PCDATA)>
<!ELEMENT y (#PCDATA)>

使用该文件和存储在 listOfPoints 中的数据样本,我想生成一个与我的 generated.dtd 结构相对应的 xml 文件

我如何在 Java 中做到这一点?

如果您有教程可以学习,那就太好了。

我知道我应该使用 JAXB:用于 XML 绑定的 Java 架构,但我不知道如何?

【问题讨论】:

    标签: java xml jaxb dtd jdom


    【解决方案1】:

    一些观察/建议:

    1) 您需要 XML 输出的样子吗?

    假设你有一个像这样的Points 类:

    import java.util.Map;
    import java.util.HashMap;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement(name = "root")
    public class Points {
    
        public Points() {};
    
        public Points(Map<Position, Double> listOfPoints) {
            this.listOfPoints = listOfPoints;
        }
    
        @XmlElement(name = "list_of_points")
        private Map<Position, Double> listOfPoints;
    
        public Map<Position, Double> getListOfPoints() {
            if (listOfPoints == null) {
                listOfPoints = new HashMap();
            }
            return this.listOfPoints;
        }
    }
    

    还有一个像这样的Position 类:

    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement(name = "position")
    public class Position {
    
        @XmlElement(required = true)
        protected String x;
        @XmlElement(required = true)
        protected String y;
    
        public String getX() {
            return x;
        }
    
        public void setX(String value) {
            this.x = value;
        }
    
        public String getY() {
            return y;
        }
    
        public void setY(String value) {
            this.y = value;
        }
    
    }
    

    不使用 DTD,您可以像这样生成 XML:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <root>
        <listOfPoints>
            <entry>
                <key>
                    <x>pos1 x</x>
                    <y>pos1 y</y>
                </key>
                <value>123.456</value>
            </entry>
            <entry>
                <key>
                    <x>pos2 x</x>
                    <y>pos2 y</y>
                </key>
                <value>456.789</value>
            </entry>
        </listOfPoints>
    </root>
    

    执行此操作的代码是:

    JAXBContext jc = JAXBContext.newInstance(Points.class);
    Marshaller marshaller = jc.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    File xml = new File("/path/to/points.xml");
    marshaller.marshal(points, xml);
    

    这足以满足您的需求吗?

    2) 使用您的 DTD

    我不确定您的 DTD 将如何帮助您,因为它暗示了一组不相关且重叠的 Java 对象,最终的 XML 将从这些对象中创建。

    要明白我的意思,请亲自尝试。

    使用xjc 工具(请参阅here),您可以从您的DTD 生成Java 对象:

    /path/to/jdk/bin/xjc -d output -p org.ajames.jaxbdemo.points -dtd my_schema.dtd
    

    使用这些 Java 类,您可以填充您的数据结构(您的listOfPoints)。然后您可以从中创建 XML 输出(如上所示,使用 JAXB 编组器)。

    但是您的 DTD 会创建一些不太有用的对象...

    那么,回到最初的问题:你希望你的 XML 看起来像什么?

    3) 使用 XSD?

    如果您手动创建所需 XML 的示例,则可以从中生成 XSD。有各种online tools 可以帮助解决这个问题。然后您可以再次使用xjc 命令(但这次是针对 XSD 而不是 DTD)。然后您可以使用生成的 Java 对象来获取您需要的确切 XML。

    【讨论】:

    • 非常感谢您,非常有帮助。
    猜你喜欢
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 2010-12-21
    相关资源
    最近更新 更多