java xml 操作 getElementById 获取到的总是 null

用的是 org.w3c.dom 中的类
我确定 id 存在的,但是获取到的总是 null。

测试代码如下:


import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;


public class XmlTest {

private static final String originXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
            "<bpmn2:definitions xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:bpmn2=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" xmlns:camunda=\"http://camunda.org/schema/1.0/bpmn\" ID=\"sample-diagram\" targetNamespace=\"http://bpmn.io/schema/bpmn\" xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd\">\n" +
            "  <bpmn2:process ID=\"Process_1\" isExecutable=\"false\">\n" +
            "    <bpmn2:startEvent ID=\"StartEvent_1w6y3xa\">\n" +
            "      <bpmn2:documentation>com.sunyard.dragon.organ.Terminal.start#.</bpmn2:documentation>\n" +
            "      <bpmn2:outgoing>SequenceFlow_0dx3fgt</bpmn2:outgoing>\n" +
            "    </bpmn2:startEvent>\n" +
            "    <bpmn2:task ID=\"Task_0mhraek\">\n" +
            "      <bpmn2:documentation>com.sunyard.dragon.organ.Switch.branch#S.</bpmn2:documentation>\n" +
            "      <bpmn2:extensionElements>\n" +
            "        <camunda:inputOutput>\n" +
            "          <camunda:inputParameter name=\"Input_2176611\">\n" +
            "            <camunda:script scriptFormat=\"S\">xml./we/request/params</camunda:script>\n" +
            "          </camunda:inputParameter>\n" +
            "        </camunda:inputOutput>\n" +
            "      </bpmn2:extensionElements>\n" +
            "      <bpmn2:incoming>SequenceFlow_0dx3fgt</bpmn2:incoming>\n" +
            "    </bpmn2:task>\n" +
            "    <bpmn2:sequenceFlow ID=\"SequenceFlow_0dx3fgt\" sourceRef=\"StartEvent_1w6y3xa\" targetRef=\"Task_0mhraek\" />\n" +
            "  </bpmn2:process>\n" +
            "  <bpmndi:BPMNDiagram ID=\"BPMNDiagram_1\">\n" +
            "    <bpmndi:BPMNPlane ID=\"BPMNPlane_1\" bpmnElement=\"Process_1\">\n" +
            "      <bpmndi:BPMNShape ID=\"StartEvent_1w6y3xa_di\" bpmnElement=\"StartEvent_1w6y3xa\">\n" +
            "        <dc:Bounds x=\"484\" y=\"92\" width=\"36\" height=\"36\" />\n" +
            "        <bpmndi:BPMNLabel>\n" +
            "          <dc:Bounds x=\"502\" y=\"128\" width=\"0\" height=\"0\" />\n" +
            "        </bpmndi:BPMNLabel>\n" +
            "      </bpmndi:BPMNShape>\n" +
            "      <bpmndi:BPMNShape ID=\"Task_0mhraek_di\" bpmnElement=\"Task_0mhraek\">\n" +
            "        <dc:Bounds x=\"452\" y=\"184\" width=\"100\" height=\"80\" />\n" +
            "      </bpmndi:BPMNShape>\n" +
            "      <bpmndi:BPMNEdge ID=\"SequenceFlow_0dx3fgt_di\" bpmnElement=\"SequenceFlow_0dx3fgt\">\n" +
            "        <di:waypoint xsi:type=\"dc:Point\" x=\"502\" y=\"128\" />\n" +
            "        <di:waypoint xsi:type=\"dc:Point\" x=\"502\" y=\"184\" />\n" +
            "        <bpmndi:BPMNLabel>\n" +
            "          <dc:Bounds x=\"517\" y=\"146\" width=\"0\" height=\"0\" />\n" +
            "        </bpmndi:BPMNLabel>\n" +
            "      </bpmndi:BPMNEdge>\n" +
            "    </bpmndi:BPMNPlane>\n" +
            "  </bpmndi:BPMNDiagram>\n" +
            "</bpmn2:definitions>\n";

    public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setValidating(true);
        factory.setNamespaceAware(true); // never forget this!

        DocumentBuilder builder = factory.newDocumentBuilder();
        InputStream is = new ByteArrayInputStream(originXml.getBytes("UTF-8"));
        Document doc = builder.parse(is);
        NodeList list = doc.getElementsByTagName("bpmn2:task");
        for (int i = 0; i < list.getLength() ; i++){
            System.out.println(list.item(i));
        }

        System.out.println(doc.getElementById("Task_0mhraek"));


    }
}

经过搜索认为问题是没有在 DTD 中定义 ID 是 ID。但是还是不会修改。

阅读 4.1k
1 个回答

请贴出你的XML文件内容和Java代码,不要随便怀疑工具问题,那都是经过反复测试和使用验证过得东西,不会轻易出问题的


【补充内容】

根据Document.getElementById()方法的javadoc描述基本确定ID类型的名称是没有预定义的,即不是“ID”或“id”,以下是javadoc描述内容:

Returns the Element that has an ID attribute with the given value. If no such element exists, this returns null . If more than one element has an ID attribute with that value, what is returned is undefined.
The DOM implementation is expected to use the attribute Attr.isId to determine if an attribute is of type ID.
Note: Attributes with the name "ID" or "id" are not of type ID unless so defined.
Parameters:
elementId The unique id value for an element.
Returns:
The matching element or null if there is none.
Since:
DOM Level 2

解决办法有三种:
1、继承Attr接口重写一个自定义类,完成ID类型名称绑定;
2、重写Document.getElementById()方法;
3、使用XPath工具。(推荐)

注:在stackoverflow上有相关问题,你可以参考,链接:http://stackoverflow.com/ques...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题