пространство имен XML при написании XML в Java - PullRequest
1 голос
/ 19 июля 2011

это мой 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.xml и test2.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 не является нулевым. Но почему в файле результатов отсутствует пространство имен?

Я пробовал три метода:

1) установите sRepairingNamespaces в значение

---- Пришла новая проблема, пространства имен были переопределены и дублированы (на самом деле «source.xml» является сложным)

2) добавить writeNamespace после writeStartElement

---- test2.xml', xmlns: book = "" `, неверно.

3) добавить setPrefix

---- без эффекта.

Спасибо.

1 Ответ

0 голосов
/ 27 декабря 2011

Заменить:

//_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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...