如何从 xml 和 java 中的根元素中删除 xmlns 属性
How to remove xmlns attribute from the root element in xml and java
我想从 xml 字符串后面删除 xmlns
属性。我写了一个 java
程序,但不确定它是否做了这里需要做的事情。
如何删除 xmlns
属性并获取修改后的 xml 字符串?
输入XML字符串:
<?xml version="1.0" encoding="UTF-8"?>
<Payment xmlns="http://api.com/schema/store/1.0">
<Store>abc</Store>
</Payment>
预期XML输出字符串:
<?xml version="1.0" encoding="UTF-8"?>
<Payment>
<Store>abc</Store>
</Payment>
Java Class:
public class XPathUtils {
public static void main(String[] args) {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>";
String afterNsRemoval = removeNameSpace(xml);
System.out.println("afterNsRemoval = " + afterNsRemoval);
}
public static String removeNameSpace(String xml) {
try {
System.out.println("before xml = " + xml);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource inputSource = new InputSource(new StringReader(xml));
Document xmlDoc = builder.parse(inputSource);
Node root = xmlDoc.getDocumentElement();
NodeList rootchildren = root.getChildNodes();
Element newroot = xmlDoc.createElement(root.getNodeName());
for (int i = 0; i < rootchildren.getLength(); i++) {
newroot.appendChild(rootchildren.item(i).cloneNode(true));
}
xmlDoc.replaceChild(newroot, root);
return xmlDoc.toString();
} catch (Exception e) {
System.out.println("Could not parse message as xml: " + e.getMessage());
}
return "";
}
}
输出:
before xml = <?xml version="1.0" encoding="UTF-8"?><Payment xmlns="http://api.com/schema/store/1.0"><Store>abc</Store></Payment>
afterNsRemoval = [#document: null]
你需要一个变压器。检查下面修改后的方法:
public static String removeNameSpace(String xml) {
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
transformer.setOutputProperty( OutputKeys.INDENT, "false" );
System.out.println("before xml = " + xml);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource inputSource = new InputSource(new StringReader(xml));
Document xmlDoc = builder.parse(inputSource);
Node root = xmlDoc.getDocumentElement();
NodeList rootchildren = root.getChildNodes();
Element newroot = xmlDoc.createElement(root.getNodeName());
for (int i = 0; i < rootchildren.getLength(); i++) {
newroot.appendChild(rootchildren.item(i).cloneNode(true));
}
xmlDoc.replaceChild(newroot, root);
DOMSource requestXMLSource = new DOMSource( xmlDoc.getDocumentElement() );
StringWriter requestXMLStringWriter = new StringWriter();
StreamResult requestXMLStreamResult = new StreamResult( requestXMLStringWriter );
transformer.transform( requestXMLSource, requestXMLStreamResult );
String modifiedRequestXML = requestXMLStringWriter.toString();
return modifiedRequestXML;
} catch (Exception e) {
System.out.println("Could not parse message as xml: " + e.getMessage());
}
return "";
}
输出:
before xml = <?xml version="1.0" encoding="UTF-8"?><Payment xmlns="http://api.com/schema/store/1.0"><Store>abc</Store></Payment>
afterNsRemoval = <?xml version="1.0" encoding="UTF-8"?><Payment><Store>abc</Store></Payment>
除了最后一个操作,你做的一切都正确:document.toString()
给你不正确的结果,因为它是生成 Document
对象的字符串 xml 表示的不正确方式。请参阅此 answer,它包含此方法的正确实现:
public static String toString(Document doc) {
try {
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
...
这是用 XPath 和 vtd 完成的代码-xml(我是作者)...
import com.ximpleware.*;
import java.io.*;
public class removeAttrNode {
public static void main(String[] s) throws VTDException, Exception{
VTDGen vg = new VTDGen(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>";
vg.setDoc(xml.getBytes());
vg.parse(false); // turn off namespace awareness so that
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
XMLModifier xm = new XMLModifier(vn);
ap.selectXPath("//@xmlns");
int i=0;
while((i=ap.evalXPath())!=-1){
xm.remove();
}
xm.output(baos);
System.out.println(baos.toString());
}
}
将 XSLT 视为删除 declared/undeclared 命名空间是一项常规任务。这里不需要第三方模块,因为 base Java 配备了 XSLT 1.0 处理器。此外,由于 XSLT 负责转换,因此不会处理循环或 XML tags/attribs 重新创建。
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class XPathUtils {
public static void main(String[] args) {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>";
String afterNsRemoval = removeNameSpace(xml);
System.out.println("afterNsRemoval = " + afterNsRemoval);
}
public static String removeNameSpace(String xml) {
try{
String xslStr = String.join("\n",
"<xsl:transform xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">",
"<xsl:output version=\"1.0\" encoding=\"UTF-8\" indent=\"no\"/>",
"<xsl:strip-space elements=\"*\"/>",
" <xsl:template match=\"@*|node()\">",
" <xsl:element name=\"{local-name()}\">",
" <xsl:apply-templates select=\"@*|node()\"/>",
" </xsl:element>",
" </xsl:template>",
" <xsl:template match=\"text()\">",
" <xsl:copy/>",
" </xsl:template>",
"</xsl:transform>");
// Parse XML and Build Document
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
Document doc = db.parse (is);
// Parse XSLT and Configure Transformer
Source xslt = new StreamSource(new StringReader(xslStr));
Transformer tf = TransformerFactory.newInstance().newTransformer(xslt);
// Output Result to String
DOMSource source = new DOMSource(doc);
StringWriter outWriter = new StringWriter();
StreamResult strresult = new StreamResult( outWriter );
tf.transform(source, strresult);
StringBuffer sb = outWriter.getBuffer();
String finalstring = sb.toString();
return(finalstring);
} catch (Exception e) {
System.out.println("Could not parse message as xml: " + e.getMessage());
}
return "";
}
}
您应该获取当前 ELEMENT_NODE 和 ownerDoc.renameNode(node,null,node.getLocalName()) 的 getOwnerDocument()。
对于您需要的所有属性,您还应该 ownerDoc.renameNode(subNode,null,subNode.getLocalName()),对于不需要的属性,您还应该使用 removeNamedItemNS。
我想从 xml 字符串后面删除 xmlns
属性。我写了一个 java
程序,但不确定它是否做了这里需要做的事情。
如何删除 xmlns
属性并获取修改后的 xml 字符串?
输入XML字符串:
<?xml version="1.0" encoding="UTF-8"?>
<Payment xmlns="http://api.com/schema/store/1.0">
<Store>abc</Store>
</Payment>
预期XML输出字符串:
<?xml version="1.0" encoding="UTF-8"?>
<Payment>
<Store>abc</Store>
</Payment>
Java Class:
public class XPathUtils {
public static void main(String[] args) {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>";
String afterNsRemoval = removeNameSpace(xml);
System.out.println("afterNsRemoval = " + afterNsRemoval);
}
public static String removeNameSpace(String xml) {
try {
System.out.println("before xml = " + xml);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource inputSource = new InputSource(new StringReader(xml));
Document xmlDoc = builder.parse(inputSource);
Node root = xmlDoc.getDocumentElement();
NodeList rootchildren = root.getChildNodes();
Element newroot = xmlDoc.createElement(root.getNodeName());
for (int i = 0; i < rootchildren.getLength(); i++) {
newroot.appendChild(rootchildren.item(i).cloneNode(true));
}
xmlDoc.replaceChild(newroot, root);
return xmlDoc.toString();
} catch (Exception e) {
System.out.println("Could not parse message as xml: " + e.getMessage());
}
return "";
}
}
输出:
before xml = <?xml version="1.0" encoding="UTF-8"?><Payment xmlns="http://api.com/schema/store/1.0"><Store>abc</Store></Payment>
afterNsRemoval = [#document: null]
你需要一个变压器。检查下面修改后的方法:
public static String removeNameSpace(String xml) {
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty( OutputKeys.METHOD, "xml" );
transformer.setOutputProperty( OutputKeys.INDENT, "false" );
System.out.println("before xml = " + xml);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource inputSource = new InputSource(new StringReader(xml));
Document xmlDoc = builder.parse(inputSource);
Node root = xmlDoc.getDocumentElement();
NodeList rootchildren = root.getChildNodes();
Element newroot = xmlDoc.createElement(root.getNodeName());
for (int i = 0; i < rootchildren.getLength(); i++) {
newroot.appendChild(rootchildren.item(i).cloneNode(true));
}
xmlDoc.replaceChild(newroot, root);
DOMSource requestXMLSource = new DOMSource( xmlDoc.getDocumentElement() );
StringWriter requestXMLStringWriter = new StringWriter();
StreamResult requestXMLStreamResult = new StreamResult( requestXMLStringWriter );
transformer.transform( requestXMLSource, requestXMLStreamResult );
String modifiedRequestXML = requestXMLStringWriter.toString();
return modifiedRequestXML;
} catch (Exception e) {
System.out.println("Could not parse message as xml: " + e.getMessage());
}
return "";
}
输出:
before xml = <?xml version="1.0" encoding="UTF-8"?><Payment xmlns="http://api.com/schema/store/1.0"><Store>abc</Store></Payment>
afterNsRemoval = <?xml version="1.0" encoding="UTF-8"?><Payment><Store>abc</Store></Payment>
除了最后一个操作,你做的一切都正确:document.toString()
给你不正确的结果,因为它是生成 Document
对象的字符串 xml 表示的不正确方式。请参阅此 answer,它包含此方法的正确实现:
public static String toString(Document doc) {
try {
StringWriter sw = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
...
这是用 XPath 和 vtd 完成的代码-xml(我是作者)...
import com.ximpleware.*;
import java.io.*;
public class removeAttrNode {
public static void main(String[] s) throws VTDException, Exception{
VTDGen vg = new VTDGen(); ByteArrayOutputStream baos = new ByteArrayOutputStream();
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>";
vg.setDoc(xml.getBytes());
vg.parse(false); // turn off namespace awareness so that
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
XMLModifier xm = new XMLModifier(vn);
ap.selectXPath("//@xmlns");
int i=0;
while((i=ap.evalXPath())!=-1){
xm.remove();
}
xm.output(baos);
System.out.println(baos.toString());
}
}
将 XSLT 视为删除 declared/undeclared 命名空间是一项常规任务。这里不需要第三方模块,因为 base Java 配备了 XSLT 1.0 处理器。此外,由于 XSLT 负责转换,因此不会处理循环或 XML tags/attribs 重新创建。
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class XPathUtils {
public static void main(String[] args) {
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Payment xmlns=\"http://api.com/schema/store/1.0\"><Store>abc</Store></Payment>";
String afterNsRemoval = removeNameSpace(xml);
System.out.println("afterNsRemoval = " + afterNsRemoval);
}
public static String removeNameSpace(String xml) {
try{
String xslStr = String.join("\n",
"<xsl:transform xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">",
"<xsl:output version=\"1.0\" encoding=\"UTF-8\" indent=\"no\"/>",
"<xsl:strip-space elements=\"*\"/>",
" <xsl:template match=\"@*|node()\">",
" <xsl:element name=\"{local-name()}\">",
" <xsl:apply-templates select=\"@*|node()\"/>",
" </xsl:element>",
" </xsl:template>",
" <xsl:template match=\"text()\">",
" <xsl:copy/>",
" </xsl:template>",
"</xsl:transform>");
// Parse XML and Build Document
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
Document doc = db.parse (is);
// Parse XSLT and Configure Transformer
Source xslt = new StreamSource(new StringReader(xslStr));
Transformer tf = TransformerFactory.newInstance().newTransformer(xslt);
// Output Result to String
DOMSource source = new DOMSource(doc);
StringWriter outWriter = new StringWriter();
StreamResult strresult = new StreamResult( outWriter );
tf.transform(source, strresult);
StringBuffer sb = outWriter.getBuffer();
String finalstring = sb.toString();
return(finalstring);
} catch (Exception e) {
System.out.println("Could not parse message as xml: " + e.getMessage());
}
return "";
}
}
您应该获取当前 ELEMENT_NODE 和 ownerDoc.renameNode(node,null,node.getLocalName()) 的 getOwnerDocument()。 对于您需要的所有属性,您还应该 ownerDoc.renameNode(subNode,null,subNode.getLocalName()),对于不需要的属性,您还应该使用 removeNamedItemNS。