在 Java 中将 XML DOM 打印为字符串时将前缀传播到子元素

Noo*_*pta 5 java xml dom xml-namespaces

我正在用 Java 中的 DOM api 创建一个 XML,如下所示

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
Element root = document.createElement("root");
document.appendChild(root);
Element one = document.createElementNS("http://ns1", "one");
root.appendChild(one);
one.setPrefix("ns1");

Element two = document.createElementNS("http://ns1", "two");
one.appendChild(two);
Run Code Online (Sandbox Code Playgroud)

当使用以下代码打印上述 DOM 时,会在所有元素上生成命名空间声明(在这种情况下,在元素一和二上)。我如何确保命名空间声明的前缀是继承的,并且转换器不会在每个元素上重新声明它们 -

代码:

public static String transformDOMtoText(final org.w3c.dom.Node domElement) throws TransformerException {

 final Transformer transformer = getTransformer();
 final DOMSource domSource = new DOMSource(domElement);

 final StringWriter stringWriter = new StringWriter();
 final StreamResult result = new StreamResult(stringWriter);
 transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$ //$NON-NLS-2$
 transformer.setOutputProperty(
   OutputKeys.OMIT_XML_DECLARATION, "yes"); //$NON-NLS-1$ //$NON-NLS-2$
 transformer.setOutputProperty(
   "{http://xml.apache.org/xslt}indent-amount", "1");

 transformer.transform(domSource, result);

 String text = stringWriter.toString();

 return text.trim();
}
Run Code Online (Sandbox Code Playgroud)

当前输出::

<root>
 <ns1:one xmlns:ns1="http://ns1">
  <two xmlns="http://ns1">
  </two>
 </ns1:one>
</root>
Run Code Online (Sandbox Code Playgroud)

预期输出::

<root>
 <ns1:one xmlns:ns1="http://ns1">
  <ns1:two>
  </ns1:two>
 </ns1:one>
</root>
Run Code Online (Sandbox Code Playgroud)

jas*_*sso 5

中的第二个属性createElementNS()限定名称(QName)。因此,如果您没有为元素名称指定前缀,则您的元素将没有前缀,并且命名空间将添加为默认命名空间。

而不是(=你写的)

Element two = document.createElementNS("http://ns1", "two");
Run Code Online (Sandbox Code Playgroud)

明确指定元素“two”所需的前缀

Element two = document.createElementNS("http://ns1", "ns1:two");
Run Code Online (Sandbox Code Playgroud)

或者从父元素中提取前缀而不是对其进行硬编码

Element two = document.createElementNS("http://ns1", one.getPrefix() + ":" + "two");
Run Code Online (Sandbox Code Playgroud)

请注意,如果未指定前缀,Node.getPrefix()它将返回null。当然,将前缀存储在 String 变量中会使事情变得更容易。

附注。这些代码示例未经测试,因此不能保证正确的结果,但我认为这是应该的。