在Java DOM(XML解析器)中的根目录下获取元素(非节点)

时间:2014-05-19 02:09:59

标签: java xml parsing dom xml-parsing

我需要在根目录下方获取元素的标记,但DOM似乎只提供获取子节点(而不是元素)的方法,并且您无法从一个节点转换为另一个节点。

http://ideone.com/SUjRmn

@Override
public void loadXml(String filepath) throws Exception {
    File f = new File(filepath);
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = null;
    Document doc = null;
    try {
        db = dbf.newDocumentBuilder();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    }
    try {
        doc = db.parse(f);
    } catch (SAXException | IOException | NullPointerException e) {
        e.printStackTrace();
    }
    Element root = doc.getDocumentElement();

    Node firstChild = root.getFirstChild();
    String tag = firstChild.getNodeName();

    //here is the problem. I can't cast from Node to Element and Node
    //stores only an int value, not the name of the object I want to restore

    ShapeDrawer drawable = null;
    switch (tag) {
        case "scribble":
            drawable = new ScribbleDrawer();
    ...

从课堂上恢复:

@Override
public void setValues(Element root) {
    NodeList nodelist = null;

    nodelist = root.getElementsByTagName("color");
    colorManager.setColor((nodelist.item(0).getTextContent()));
    this.color = colorManager.getCurrentColor();
    System.out.println(color.toString());

    nodelist = root.getElementsByTagName("pressx");
    pressx = Integer.parseInt(nodelist.item(0).getTextContent());
    System.out.println(pressx);

    nodelist = root.getElementsByTagName("pressy");
    pressy = Integer.parseInt(nodelist.item(0).getTextContent());
    System.out.println(pressy);

    nodelist = root.getElementsByTagName("lastx");
    lastx = Integer.parseInt(nodelist.item(0).getTextContent());

    nodelist = root.getElementsByTagName("lasty");
    lasty = Integer.parseInt(nodelist.item(0).getTextContent());
}

public void toDOM(Document doc, Element root) {
    System.out.println("ScribbleDrawer being saved");
    Element shapeBranch = doc.createElement("scribble");
    Attr attr1 = doc.createAttribute("hashcode");
    attr1.setValue(((Integer) this.hashCode()).toString());
    shapeBranch.setAttributeNode(attr1);
    root.appendChild(shapeBranch);
    Element eColor = doc.createElement("color");
    eColor.setTextContent(colorManager.namedColorToString(color));
    shapeBranch.appendChild(eColor);

    // creating tree branch
    Element press = doc.createElement("press");

    Attr attr2 = doc.createAttribute("pressx");
    attr2.setValue(((Integer) pressy).toString());
    press.setAttributeNode(attr2);

    Attr attr3 = doc.createAttribute("pressy");
    attr3.setValue(((Integer) pressy).toString());
    press.setAttributeNode(attr3);

    shapeBranch.appendChild(press);

    Element last = doc.createElement("last");

    Attr attr4 = doc.createAttribute("lastx");
    attr4.setValue(((Integer) lastx).toString());
    last.setAttributeNode(attr4);

    Attr attr5 = doc.createAttribute("lasty");
    attr5.setValue(((Integer) lasty).toString());
    last.setAttributeNode(attr5);

    shapeBranch.appendChild(last);
}

我知道其他解析器更容易,但我差不多完成了,当涉及多态时,JAXB似乎与Option-marshalling等一样复杂

编辑:这就是xml的样子;而不是" scribble"其他标签/多态子代是可能的,它们从不同的实例变量反序列化(因此除了根之外的不同DOM树)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Drawables>
  <scribble hashcode="189680059">
    <color>Black</color>
    <press pressx="221" pressy="221"/>
    <last lastx="368" lasty="219"/>
  </scribble>
  <scribble hashcode="1215837841">
    <color>Black</color>
    <press pressx="246" pressy="246"/>
    <last lastx="368" lasty="221"/>
  </scribble>

1 个答案:

答案 0 :(得分:0)

如果您的节点是元素,则可以从节点转换为元素。但是,您的第一个孩子也可能是一个文本节点,当然也不能投射。您必须在投射前测试NodeType的节点。

如果您的XML没有使用名称空间,您可以使用这样的方法来提取您的子元素。它接收节点列表,测试每个节点并返回仅包含元素的列表:

public static List getChildren(Element element) {
    List<Element> elements = new ArrayList<>();
    NodeList nodeList = element.getChildNodes();
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node node = nodeList.item(i);
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            elements.add((Element) node);
        }
    }
    return elements;
}

另一种方法是使用已包含此类实用程序方法的API,如DOM4J或JDOM。