我有一个XML字符串/对象:
<?xml version="1.0"?>
<ns0:top xmlns:ns0="someUrl1">
<ns1:child xmlns:ns1="someUrl2">
Value
</ns1:child>
</ns0:top>
如何转换为&#34;标准化&#34;名称空间XML形式如下:
<?xml version="1.0"?>
<ns0:top xmlns:ns0="someUrl1" xmlns:ns1="someUrl2">
<ns1:child>
Value
</ns1:child>
</ns0:top>
答案 0 :(得分:0)
这可能是一个坏主意,原因有几个(很难涵盖很多边缘情况),但是(为了好玩和非常简单的情况,比如你提出的那个),这是一个使用SAXParser实现这一点的实现:
/* package whatever; // don't place package name! */
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone extends DefaultHandler
{
StringBuilder sb;
private Hashtable namespaces;
private int nsIdx;
boolean rootDone;
String rootNodeName;
String rootNS;
public void startDocument() throws SAXException {
namespaces = new Hashtable();
nsIdx = 0;
sb = new StringBuilder();
rootDone = false;
}
public void endDocument() throws SAXException {
Set<String> keys = namespaces.keySet();
StringBuilder rootEl = new StringBuilder();
rootEl.append("<" + namespaces.get(rootNS) + ":" + rootNodeName);
for(String key: keys){
rootEl.append(" xmlns:" + namespaces.get(key) + "='" + key + "'");
}
rootEl.append(">");
sb.insert(0, rootEl.toString());
System.out.println(sb.toString());
}
public void characters(char[] ch, int start, int length) throws SAXException {
for (int i = start; i < start + length; i++)
{
sb.append(ch[i]);
}
}
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if (!namespaces.containsKey(namespaceURI))
{
nsIdx++;
namespaces.put(namespaceURI, "ns" + nsIdx);
}
boolean printEl = rootDone;
if (!rootDone)
{
rootNodeName = localName;
rootNS = namespaceURI;
rootDone = true;
}
else
{
sb.append("<" + namespaces.get(namespaceURI) + ":" + localName);
}
for (int i = 0; i < atts.getLength(); i++)
{
if (!namespaces.containsKey(atts.getURI(i)))
{
nsIdx++;
namespaces.put(atts.getURI(i),"ns" + nsIdx);
}
if (atts.getLocalName(i) == atts.getQName(i))
{
sb.append(" " + atts.getLocalName(i) + "='" + atts.getValue(i) + "'");
}
else
{
sb.append(" " + namespaces.get(atts.getURI(i)) + ":" + atts.getLocalName(i) + "='" + atts.getValue(i) + "'");
}
}
if (printEl)
{
sb.append(">");
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
sb.append("</" + namespaces.get(uri) + ":" + localName + ">");
}
public static void main (String[] args) throws java.lang.Exception
{
String xml = "<?xml version=\"1.0\"?><ns0:top xmlns:ns0=\"someUrl1\"><ns1:child xmlns:ns1=\"someUrl2\" ns0:testNS=\"tstNS\" test=\"tst\">Value</ns1:child><child2></child2><child3/></ns0:top>";
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
SAXParser saxParser = spf.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(new Ideone());
xmlReader.parse(new InputSource(new StringReader(xml)));
}
}
(ideone:http://ideone.com/E4LIac)
请注意,这将执行以下可能不合需要的事情:
<child3 />
变为<child3></child3>
)xmlns:ns3=''
)另请注意,它只会将最终结果打印到System.out
- 您可能希望将其返回或保存或其他内容。我不知道这是否或如何在groovy中工作。