如何避免xmlns =""要添加到受操纵的XML根元素?

时间:2018-01-20 23:50:46

标签: java xml

我按如下方式更改jta-data-source的{​​{1}}值:

persistence.xml

(因为How to create a ShrinkWrap PersistenceDescriptor from an existing persistence.xml?尚未得到答复)。

除了JavaArchive jarArchive = Maven.configureResolver().workOffline().resolve("richtercloud:project1-jar:jar:1.0-SNAPSHOT").withoutTransitivity().asSingle(JavaArchive.class); Node persistenceXml = jarArchive.get("META-INF/persistence.xml"); DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document persistenceXmlDocument = documentBuilder.parse(persistenceXml.getAsset().openStream()); //asked //https://stackoverflow.com/questions/46771622/how-to-create-a-shrinkwrap-persistencedescriptor-from-an-existing-persistence-xm //for how to manipulate persistence.xml more easily with //ShrinkWrap's PersistenceDescriptor XPathFactory xPathfactory = XPathFactory.newInstance(); XPath xpath = xPathfactory.newXPath(); XPathExpression expr = xpath.compile("//persistence-unit/jta-data-source"); org.w3c.dom.Node persistenceXmlDataSourceNode = (org.w3c.dom.Node) expr.evaluate(persistenceXmlDocument, XPathConstants.NODE); persistenceXmlDataSourceNode.setTextContent("jdbc/project1-test-db"); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); //transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); //was there before, but unclear why StringWriter writer = new StringWriter(); transformer.transform(new DOMSource(persistenceXmlDocument), new StreamResult(writer)); String persistenceUnit = writer.toString(); 属性添加到根xmlns=""元素下的persistence-unit之外,其效果很好,这似乎会导致:

  

java.io.IOException:org.xml.sax.SAXParseException; lineNumber:2; columnNumber:108;存档中的部署描述符文件META-INF / persistence.xml [project1-jar-1.0-SNAPSHOT.jar]。 cvc-complex-type.2.4.a:从元素' persistence-unit'开始发现无效内容。 ' {" http://xmlns.jcp.org/xml/ns/persistence":persistence-unit}'是预期的。

我没有坚持使用Transformer和相关课程的想法。

1 个答案:

答案 0 :(得分:1)

不知道为什么我无法在Java SE中重现这一点,但问题是javax.xml.parsers.DocumentBuilder默认情况下不会识别命名空间,因此在操作文档期间命名空间信息会丢失因此,xmlns添加了空Transformer

现在DocumentBuilder可以识别名称空间,XPath解析不起作用,查询返回null,请参阅XPath returning null for "Node" when isNameSpaceAware and isValidating are "true"以获取详细说明以及有关XPath名称空间感知问题的更多详细信息(我无法获得构建自定义NamespaceContext的解决方案。)

为了避免这种情况,我最终调整了我的XPath查询,以使用How to ignore namespace when selecting XML nodes with XPath中描述的local-name函数。即//*[local-name()='jta-data-source']

为了避免新创建的元素出现空Document.createElementNS属性,仍然需要使用createElement代替xmlns,有关说明,请参阅Empty default XML namespace xmlns="" attribute being added?