开发者

xml namespace when writing xml in java

this is my 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>

The source code test.java, It divides the source.xml into two xml file, test1.xml and test2.xml; it uses DefaultHandler and 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;
    }
}

}

the result file, test1.xml:

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

You know, it is wrong. The namespace of 'manifext' is missing, Prefix "manifest" can not be resolved to namespace URI.

What I want is:

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

Through the debugging, I found the following statement was successfully called.

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

The third parameter of writeStartElement is not null. But why is the namespace missing in the result file?

I tried three methods:

1) set sRepairingNamespaces to be true

----New trouble come, the namespaces were redeclared and duplicate.(In fact, 'source.xml' is complicated)

2) add writeNamespace after writeStartElement

----test2.xml',xmlns:book=""`, wrong.

3) add setPrefix

----no effect.

Thanks.


Replace:

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

with:

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

This gives the following outputs:

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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜