2016-09-07 83 views
0

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

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 

我必须用类似的方式来声明命名空间的转型水平?请任何人,帮助我吗?

在此先感谢。

+0

谢谢!我刚刚添加了错误消息。 – drusilabs

+0

堆栈跟踪可能是有用的。我在这里猜测,但似乎你的基本文档是无效的,而不是你自己的转换(堆栈跟踪会告诉我们,如果遇到的错误是在文档解析级别或XPath评估级别)。 – GPI

+1

请注意,XSLT和XPath需要名称空间感知的DocumentBuilderFactory,因此在创建DocumentBuilder并使用命名空间解析XML文档之前,请确保您首先在您的DocumentBuilderFactory上使用'setNamespaceAware(true)'。 –

回答

0

基于由马丁Honnen提出我能解决我的问题评论:

注意,XSLT和XPath需要一个命名空间感知的DocumentBuilderFactory所以一定要确保你第一次使用setNamespaceAware(真)对你的DocumentBuilderFactory创建DocumentBuilders前并使用命名空间解析XML文档