drusilabs drusilabs - 1 month ago 14
Java Question

Namespace not declared at XML Node Transformation

I am trying to process a bpmn file into an own flow model. Actually, my problem does not relate at all to bpmn standard so consider this as a context issue.
I want to get an xml node and transform it to String in order to save later to a database.
What i am trying to do in the following code is to get the BPMNDiagram node, using xpath, and export it to as string but, when i try to export i get an expception about not declaring nsi namespace.
I have declared all the namespaces at xpath previous "query" but once i get this node and try to transform it, i get the error described below.
The xpath part is working properly since i am getting the right node. The problem appears at transformation phase.

XML File (partial)

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


This is my code:

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


Error message:

Namespace for prefix 'nsi' has not been declared


Do i have to declare in a similar way the namespaces at transformation level? Can anybody, please, help me?

Thanks in advance.

Answer

Based on a comment made by Martin Honnen i could solve my issue:

"Note that XSLT and XPath need a namespace aware DocumentBuilderFactory so make sure you first use setNamespaceAware(true) on your DocumentBuilderFactory before creating DocumentBuilders and parsing XML documents with namespaces"

Comments