我需要使用 SAX 解析器进行 xml 转换,为此我需要从 xml 中删除 namespace 。由于我们正在处理巨大的 xml,因此我需要使用 SAX 解析器。
示例输入 xml:
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://www.w3.org/2003/05/soap-envelope"
xmlns:ns2="http://www.google.com/generation/type">
<ns2:meta>
<gender xmlns="" xmlns:ns5="http://www.google.com/generation">M</gender>
<dateOfBirth xmlns="" xmlns:ns5="http://www.google.com/generation">1976-07-19</dateOfBirth>
<ns2:languageRef>ENG</ns2:languageRef>
</ns2:meta>
<root>
在 SAX 解析器的帮助下,我需要以下输出。
<root>
<meta>
<gender>M</gender>
<dateOfBirth>1976-07-19</dateOfBirth>
<languageRef>ENG</languageRef>
</ns2:meta>
<root>
提前致谢..
我尝试过的代码,
我尝试使用 XMLFlterImpl,
XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
if (qName.contains(":")) {
String[] data = data = qName.split(":");
super.startElement(uri, localName, data[1], atts);
} else {
super.startElement(uri, localName, qName, atts);
}
}
这会删除元素名称前缀(命名空间),但不确定如何删除命名空间属性
最佳答案
编辑:
好的,根据 @MichaelKay 的评论指导,这是我的更新答案。
从标签中删除命名空间:
正如他的回答中所建议的,startElement
应该有""
代替uri
。 结束标签怎么样?:
在你的问题中我不明白你为什么想要 ns2
结束meta
标签,特别是当您想要删除起始标签时。
我假设您也希望将其删除作为结束标记。同样endElement
还应该有""
代替uri
。
过滤 XMLNS 属性:
您可以创建一个新的 AttributesImpl
。然后浏览属性列表并检查 QName
是否以 xmlns
开头,如果没有将其添加到 AttributesImpl
并在 startElement
中使用它如:
super.startElement("", localName, data[1], aImpl);
另请注意,根据@MartinHonnen,是的属性'uri
也应该是“”并且也是qName
应该像元素一样没有前缀。但是,如果您想保留属性名称(我认为您不想这样做),您可以保留 atts.getQName(i)
照原样。
还将命名空间功能设置为 false,例如:
xf.setFeature("http://xml.org/sax/features/namespaces", false);
代码:
try {
InputSource file = new InputSource("filterns.xml");
XMLFilterImpl xf = new XMLFilterImpl(
XMLReaderFactory.createXMLReader()) {
@Override
public void startElement(String uri, String localName,
String qName, Attributes atts) throws SAXException {
AttributesImpl aImpl = new AttributesImpl();
int l = atts.getLength();
for (int i = 0; i < l; i++) {
if (atts.getQName(i) != null
&& atts.getQName(i).startsWith("xmlns")) {
continue;
} else {
String aQName = atts.getQName(i);
String[] s = aQName.split(":");
if (s.length > 1) {
aQName = s[1];
}
aImpl.addAttribute("",
atts.getLocalName(i), aQName,
atts.getType(i), atts.getValue(i));
}
}
String[] s = qName.split(":");
if (s.length > 1) {
super.startElement("", localName, s[1], aImpl);
} else {
super.startElement("", localName, qName, aImpl);
}
}
@Override
public void endElement(String uri, String localName,
String qName) throws SAXException {
String[] s = qName.split(":");
if (s.length > 1) {
super.endElement("", localName, s[1]);
} else {
super.endElement("", localName, qName);
}
}
@Override
public void startPrefixMapping(String prefix, String uri) {
}
};
xf.setFeature("http://xml.org/sax/features/namespaces", false);
SAXSource src = new SAXSource(xf, file);
StringWriter stringWriter = new StringWriter();
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes");
transformer.transform(src, new StreamResult(stringWriter));
String xml = stringWriter.toString();
System.out.println(xml);
} catch (Exception e) {
e.printStackTrace();
}
关于java - 如何使用 SAX 解析器删除 xml 命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44969384/