如何使用java dom从xml中删除命名空间?
我有以下代码
DocumentBuilderFactory dbFactory_ = DocumentBuilderFactory.newInstance(); Document doc_; DocumentBuilder dBuilder = dbFactory_.newDocumentBuilder(); StringReader reader = new StringReader(s); InputSource inputSource = new InputSource(reader); doc_ = dBuilder.parse(inputSource); doc_.getDocumentElement().normalize();
然后我就能做到
doc_.getDocumentElement();
并得到我的第一个元素,但问题是,而不是job
元素是tns:job
。
我知道并试图使用:
dbFactory_.setNamespaceAware(true);
但这不是我想要的东西,我需要一些东西来完全摆脱命名空间。
任何帮助将不胜感激,谢谢,
玩笑
对于元素和属性节点:
Node node = ...; String name = node.getLocalName();
将为您提供节点名称的本地部分。
请参见Node.getLocalName()
使用正则表达式function。 这将解决这个问题:
public static String removeXmlStringNamespaceAndPreamble(String xmlString) { return xmlString.replaceAll("(<\\?[^<]*\\?>)?", ""). /* remove preamble */ replaceAll("xmlns.*?(\"|\').*?(\"|\')", "") /* remove xmlns declaration */ .replaceAll("(<)(\\w+:)(.*?>)", "$1$3") /* remove opening tag prefix */ .replaceAll("()(\\w+:)(.*?>)", "$1$3"); /* remove closing tags prefix */ }
而不是
dbFactory_.setNamespaceAware(true);
使用
dbFactory_.setNamespaceAware(false);
虽然我同意Tomalak:一般来说,命名空间比有害更有帮助。 你为什么不想用它们?
编辑:这个答案没有回答OP的问题,即如何摆脱名称空间前缀 。 RD01提供了正确的答案。
如果绝对必须这样做,您可以预处理XML以删除所有名称空间。 我建议不要这样做,因为从XML文档中删除命名空间实际上与从编程框架或库中删除命名空间相当 – 冒着名称冲突的风险,并且无法区分曾经不同的元素。 但是,这是你的葬礼。 😉
此XSLT转换从任何XML文档中删除所有名称空间。
将其应用于XML文档。 即使在这个网站上,做这样的事情的Java例子应该很多。 生成的文档将完全具有相同的结构和布局,只是没有名称空间。
public static void wipeRootNamespaces(Document xml) { Node root = xml.getDocumentElement(); NodeList rootchildren = root.getChildNodes(); Element newroot = xml.createElement(root.getNodeName()); for (int i=0;i
Tomalak,XSLT的一个修复程序(在第3个模板中):
选择解决方案时,还需要考虑输入xml的大小。 对于大型xmls,大小约为100k,如果您的输入来自Web服务,则还需要考虑操作大字符串时的垃圾收集含义。 之前我们使用过String.replaceAll,由于replaceAll的实现方式,它在生产中导致了1.5G堆大小的频繁OOM。
您可以参考http://app-inf.blogspot.com/2013/04/pitfalls-of-handling-large-string.html获取我们的研究结果。
我不确定XSLT如何处理大型String对象,但我们最终解析了字符串manualy以在一个解析中删除前缀以避免创建其他大型java对象。
public static String removePrefixes(String input1) { String ret = null; int strStart = 0; boolean finished = false; if (input1 != null) { //BE CAREFUL : allocate enough size for StringBuffer to avoid expansion StringBuffer sb = new StringBuffer(input1.length()); while (!finished) { int start = input1.indexOf('<', strStart); int end = input1.indexOf('>', strStart); if (start != -1 && end != -1) { // Appending anything before '<', including '<' sb.append(input1, strStart, start + 1); String tag = input1.substring(start + 1, end); if (tag.charAt(0) == '/') { // Appending '/' if it is "" sb.append('/'); tag = tag.substring(1); } int colon = tag.indexOf(':'); int space = tag.indexOf(' '); if (colon != -1 && (space == -1 || colon < space)) { tag = tag.substring(colon + 1); } // Appending tag with prefix removed, and ">" sb.append(tag).append('>'); strStart = end + 1; } else { finished = true; } } //BE CAREFUL : use new String(sb) instead of sb.toString for large Strings ret = new String(sb); } return ret; }
而不是使用TransformerFactory,然后调用它上面的转换(这是注入空命名空间,我转换如下:
OutputStream outputStream = new FileOutputStream(new File(xMLFilePath)); OutputFormat outputFormat = new OutputFormat(doc, "UTF-8", true); outputFormat.setOmitComments(true); outputFormat.setLineWidth(0); XMLSerializer serializer = new XMLSerializer(outputStream, outputFormat); serializer.serialize(doc); outputStream.close();