在java中编写xml时的xml命名空间

时间:2011-07-19 08:54:48

标签: java xml namespaces

这是我的source.xml

<?xml version="1.0" encoding="UTF-8"?>
<zip:archive xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" xmlns:zip="com.test.zip">
<zip:entry zip:target="test1.xml"><manifest:t>aaa</manifest:t></zip:entry>
<zip:entry zip:target="test2.xml"><book>hacker and painter</book></zip:entry>
</zip:archive>

源代码test.java,它将source.xml分为两个xml文件,test1.xmltest2.xml;它使用DefaultHandler和XMLStreamWriter:

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class test {

public static void main(String[] args) throws Exception {
    SAXParserFactory spf;
    SAXParser saxParser;
    spf = SAXParserFactory.newInstance();
    spf.setNamespaceAware(true);
    spf.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
    saxParser = spf.newSAXParser();
    saxParser.parse(new File("source.xml"), new myDefaultHandler());
    System.out.println("Done");
}

}

class myDefaultHandler extends DefaultHandler {
private XMLStreamWriter _delegateWriter = null;
private String lastTargetFile = "";
private Boolean bDivide = false;

@Override
public void characters(char ch[], int start, int length)
        throws SAXException {
    if (bDivide) {
        try {
            String ss = new String(ch, start, length);
            _delegateWriter.writeCharacters(ss);
        } catch (XMLStreamException e) {}
    }
}

@Override
public void endDocument() throws SAXException {
}

@Override
public void endElement(String uri, String localName, String qName) {
    if (bDivide && _delegateWriter!=null && !localName.equals("entry")&& !localName.equals("archive")) {
        try {
            _delegateWriter.writeEndElement();
        } catch (XMLStreamException e) {                
        }
        if (localName.equals("entry")) {
            try {
                _delegateWriter.writeEndDocument();
                _delegateWriter.flush();
                _delegateWriter.close();
            } catch (XMLStreamException e) {
            }
        }
    }
}

@Override
public void startDocument() throws SAXException {

}

@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    if (localName.equals("archive") || qName.equals("zip:archive")) 
    {
        bDivide = false;
    } 
    else if (localName.equals("entry")|| qName.equals("zip:entry")) 
    {
        bDivide = false;
        int attrCount = attributes.getLength();
        if (attrCount > 0) {
            for (int i = 0; i < attrCount; i++) {
                if (attributes.getLocalName(i).equals("target")) {
                    lastTargetFile = attributes.getValue(i);
                    XMLOutputFactory xof = XMLOutputFactory.newInstance();
                        //xof.setProperty("javax.xml.stream.isRepairingNamespaces", new Boolean( true ));
                    try {
                        _delegateWriter = xof.createXMLStreamWriter(new FileOutputStream(new File(lastTargetFile)), "UTF-8");
                        _delegateWriter.writeStartDocument("UTF-8", "1.0");
                    } catch (FileNotFoundException e) {
                    } catch (XMLStreamException e) {
                    }
                }
            }
        }
    } 
    else {
        bDivide = true;

        try 
        {
            //_delegateWriter.setPrefix(prefixFromqName(localName,qName),uri);
            _delegateWriter.writeStartElement(prefixFromqName(localName,qName), localName, uri);
            //_delegateWriter.writeNamespace(prefixFromqName(localName,qName), uri);


            int attrCount1 = attributes.getLength();
            if (attrCount1 > 0) {
                System.out.println("Attributes:");
                for (int i = 0; i < attrCount1; i++) {
                    String attUri = attributes.getURI(i);
                    if (attUri != null)
                        _delegateWriter.writeAttribute(attUri, attributes.getLocalName(i), attributes.getValue(i));
                    else
                        _delegateWriter.writeAttribute(attributes.getLocalName(i), attributes.getValue(i));
                }
            }
        } 
        catch (XMLStreamException e) {
        }
    }       
}

public String prefixFromqName(String localName, String qName) {
    // localName=archive
    // qName=pzip:archive
    int index = qName.indexOf(':');
    if (index > -1) {
        return qName.substring(0, index);
    } else {
        return qName;
    }
}

}

结果文件test1.xml:

<? xml version="1.0" encoding="UTF-8"?><manifest:t>aaa</manifest:t>

你知道,这是错的。缺少'manifext'的命名空间,前缀“manifest”无法解析为命名空间URI。

我想要的是:

<? xml version="1.0" encoding="UTF-8"?><manifest:t xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">aaa</manifest:t>

通过调试,我发现成功调用了以下语句。

XMLStreamWriter.writeStartElement("manifest", "manifest", "urn:oasis:names:tc:opendocument:xmlns:manifest:1.0");

writeStartElement的第三个参数不为null。但是为什么结果文件中缺少命名空间?

我尝试了三种方法:

1)将sRepairingNamespaces设为真

----新的麻烦来了,命名空间被重新声明并重复。(事实上,'source.xml'很复杂)

2)在writeNamespace

之后添加writeStartElement

---- test2.xml', xmlns:book =“”`,错误。

3)添加setPrefix

----没效果。

感谢。

1 个答案:

答案 0 :(得分:0)

替换:

//_delegateWriter.setPrefix(prefixFromqName(localName,qName),uri);
_delegateWriter.writeStartElement(prefixFromqName(localName,qName), localName, uri);
//_delegateWriter.writeNamespace(prefixFromqName(localName,qName), uri);

使用:

if(!"".equals(uri)){
    _delegateWriter.writeStartElement(prefixFromqName(localName, qName), localName, uri);
    _delegateWriter.writeNamespace(prefixFromqName(localName,qName), uri);
}else{
    _delegateWriter.writeStartElement(localName);
}

这给出了以下输出:

test1.xml:

<?xml version="1.0" encoding="UTF-8"?><manifest:t xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">aaa</manifest:t>

test2.xml:

<?xml version="1.0" encoding="UTF-8"?><book>hacker and painter</book>