【问题标题】:Namespace not declared at XML Node Transformation名称空间未在 XML 节点转换中声明
【发布时间】:2016-09-07 13:01:50
【问题描述】:

我正在尝试将 bpmn 文件处理为自己的流模型。实际上,我的问题根本与 bpmn 标准无关,因此请将此视为上下文问题。 我想获取一个 xml 节点并将其转换为 String 以便稍后保存到数据库中。 我在以下代码中尝试做的是使用 xpath 获取 BPMNiagram 节点,并将其导出为字符串,但是,当我尝试导出时,我得到一个关于未声明 nsi 命名空间的异常。 我已经在 xpath 之前的“查询”中声明了所有命名空间,但是一旦我得到这个节点并尝试对其进行转换,我就会得到下面描述的错误。 xpath 部分工作正常,因为我得到了正确的节点。问题出现在转型阶段。

XML 文件(部分)

<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"     xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="1.2.1">
<bpmn:process id="PP-ProcessProva01" name="ProcesProva" isExecutable="true">
...
</bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="PP-ProcessProva01">
  <bpmndi:BPMNShape id="StartEvent_1cp968c_di" bpmnElement="PP_EV_ENTRADA">
    <dc:Bounds x="-39" y="143" width="36" height="36" />
    <bpmndi:BPMNLabel>
      <dc:Bounds x="70" y="161" width="90" height="20" />
    </bpmndi:BPMNLabel>
  </bpmndi:BPMNShape>
  <bpmndi:BPMNShape id="Task_0ogrwwq_di" bpmnElement="PP_AC_VALIDACION">
    <dc:Bounds x="241.17552742616033" y="120.96118143459915" width="100" height="80" />
  </bpmndi:BPMNShape>
  <bpmndi:BPMNEdge id="SequenceFlow_1bc244v_di" bpmnElement="EV_TR_PP_EV_ENTRADA-PP_AC_VALIDACION">
    <di:waypoint xsi:type="dc:Point" x="-3" y="161" />
    <di:waypoint xsi:type="dc:Point" x="241" y="161" />
    <bpmndi:BPMNLabel>
      <dc:Bounds x="21.459854014598534" y="151" width="90" height="20" />
    </bpmndi:BPMNLabel>
  </bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn:definitions>

这是我的代码:

String res="";
File file2 = new File("c:\\temp\\prova.bpmn");

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
org.w3c.dom.Document doc = dbf.newDocumentBuilder().parse(file2);

HashMap<String, String> prefMap = new HashMap<String, String>() {{
                put("bpmn", "http://www.omg.org/spec/BPMN/20100524/MODEL");
                put("bpmndi", "http://www.omg.org/spec/BPMN/20100524/DI");
                put("di", "http://www.omg.org/spec/DD/20100524/DI");
                put("dc", "http://www.omg.org/spec/DD/20100524/DC");
                put("xsi", "http://www.w3.org/2001/XMLSchema-instance");
                put("camunda", "http://camunda.org/schema/1.0/bpmn");
            }};
SimpleNamespaceContext namespaces = new SimpleNamespaceContext(prefMap);

javax.xml.xpath.XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setNamespaceContext(namespaces);
javax.xml.xpath.XPathExpression expr = xpath.compile("/definitions/BPMNDiagram");
Node nodeDi = (Node) expr.evaluate(doc,XPathConstants.NODE);



Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.transform(new DOMSource(nodeDi), new StreamResult(res));

错误信息:

Namespace for prefix 'nsi' has not been declared

我是否必须以类似的方式在转换级别声明命名空间?有人可以帮帮我吗?

提前致谢。

【问题讨论】:

  • 谢谢!我刚刚添加了错误消息。
  • 堆栈跟踪可能很有用。我在这里猜测,但您的基本文档似乎无效,而不是您的转换本身(堆栈跟踪将告诉我们您遇到的错误是在文档解析级别还是在 XPath 评估级别)。跨度>
  • 请注意,XSLT 和 XPath 需要一个可识别命名空间的 DocumentBuilderFactory,因此请确保在创建 DocumentBuilder 和使用命名空间解析 XML 文档之前首先在 DocumentBuilderFactory 上使用 setNamespaceAware(true)
  • 您好 Martin,请问您能回答我的问题而不是发表评论吗?感谢您的建议,我已经能够解决我的问题,但它的优点完全是您的。我会标记为正确答案。
  • @drusilabs,如果回答者不在,您可以自己添加回答。它将帮助其他研究人员。

标签: java xml dom bpmn


【解决方案1】:

根据 Martin Honnen 的评论,我可以解决我的问题:

请注意,XSLT 和 XPath 需要一个可识别命名空间的 DocumentBuilderFactory,因此请确保在创建 DocumentBuilder 和解析带有命名空间的 XML 文档之前首先在 DocumentBuilderFactory 上使用 setNamespaceAware(true)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-13
    • 2016-10-30
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多