我按如下方式更改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和相关课程的想法。
答案 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?。