问题描述
我正在更改 persistence.xml
的 jta-data-source
值,如下所示:
I'm changing the jta-data-source
value of a persistence.xml
as follows:
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();
(由于 如何创建 ShrinkWrap来自现有 persistence.xml 的 PersistenceDescriptor? 尚未得到答复).
(since How to create a ShrinkWrap PersistenceDescriptor from an existing persistence.xml? has not been answered, yet).
这很好用,除了在根 persistence
元素下添加到 persistence-unit
的 xmlns=""
属性似乎原因:
That works fine, except for a xmlns=""
attribute added to the persistence-unit
under the root persistence
element which seems to cause:
java.io.IOException: org.xml.sax.SAXParseException;行号:2;列数:108;存档 [project1-jar-1.0-SNAPSHOT.jar] 中的部署描述符文件 META-INF/persistence.xml.cvc-complex-type.2.4.a:发现以元素persistence-unit"开头的无效内容.'{"http://xmlns.jcp.org/xml/ns/persistence":persistence-unit}'.
I'm not adhering to the idea to use Transformer and related classes.
推荐答案
既然 DocumentBuilder
是命名空间感知的,XPath 解析不起作用并且查询返回 null
,请参阅 XPath 为节点"返回空值当 isNameSpaceAware 和 isValidating 为true"时,有关 XPath 名称空间感知问题的详细描述和更多详细信息(我无法获得构建自定义 NamespaceContext 的解决方案才能工作).
Now that DocumentBuilder
is namespace aware, XPath resolution doesn't work and queries return null
, see XPath returning null for "Node" when isNameSpaceAware and isValidating are "true" for a detailed description and more details on the XPath namespace awareness issue (I couldn't get the solution to build a custom NamespaceContext to work).
为了避免这种情况,我最终调整了我的 XPath 查询以使用 local-name
函数,如 如何在使用 XPath 选择 XML 节点时忽略命名空间.即 //*[local-name()='jta-data-source']
.
In order to avoid this I finally adjusted my XPath query to use the local-name
function as described at How to ignore namespace when selecting XML nodes with XPath. i.e. //*[local-name()='jta-data-source']
.
仍然需要使用 Document.createElementNS
而不是 createElement
以避免在新创建的元素上出现空的 xmlns
属性,参见 空的默认 XML 命名空间 xmlns="";正在添加属性? 解释一下.
It's still necessary to use Document.createElementNS
instead of createElement
in order to avoid empty xmlns
attribute on newly created elements, see Empty default XML namespace xmlns="" attribute being added? for an explanation.
这篇关于如何避免 xmlns=""要添加到操纵的 XML 根元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!