Могу ли я поместить все определения namspace в элемент верхнего уровня с помощью JAXB - PullRequest
2 голосов
/ 24 мая 2011

При использовании кода, созданного вручную, мой xml был таким:

    <?xml version="1.0" encoding="UTF-8"?>
    <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#" 
    xmlns:ext="http://musicbrainz.org/ns/ext-1.0#">
    <artist-list offset="0" count="8">
    <artist type="Person" id="00ed154e-8679-42f0-8f42-e59bd7e185af" 
    ext:score="100">

Теперь я использую JAXB, что намного лучше, но хотя xml и является вполне допустимым, мне нужно заставить его поместить xmlns: ext = "http://musicbrainz.org/ns/ext#-1.0" внутри элемента метаданных, а не элемента Artist для совместимости с клиентским кодом, который я не могу контролировать.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <metadata xmlns="http://musicbrainz.org/ns/mmd-1.0#">
    <artist-list offset="0" count="4">
    <artist type="Person" id="00ed154e-8679-42f0-8f42-e59bd7e185af" 
    ext:score="100" xmlns:ext="http://musicbrainz.org/ns/ext#-1.0">

Можно ли это сделать, пожалуйста?

РЕДАКТИРОВАТЬ: Обойти его с помощью String replaceпотому что мне нужно иметь дело только с одним конкретным случаем

    String xml = sw.toString();

    //Remove extension namespace definition
    xml=xml.replace("xmlns:ext=\"http://musicbrainz.org/ns/ext#-1.0","");

    //Add it to the top instead
    xml=xml.replace("<metadata xmlns=\"http://musicbrainz.org/ns/mmd-1.0#\">",
                     "<metadata xmlns=\"http://musicbrainz.org/ns/mmd-1.0#\" xmlns:ext=\"http://musicbrainz.org/ns/ext-1.0#\">");

    //Now write out to the proper output stream
    out.write(xml);

Ответы [ 2 ]

1 голос
/ 24 мая 2011

Я не думаю, что есть способ сделать это, используя JAXB, но вот быстрый постпроцессор, использующий Dom4J :

public static void moveNameSpacesToRoot(Document document) {
    final Element rootElement = document.getRootElement();
    moveNameSpacesToRootElement(rootElement, rootElement);
}

@SuppressWarnings("unchecked")
private static void moveNameSpacesToRootElement(
    Element thisElement, Element rootElement) {
    if (!thisElement.equals(rootElement)) {
        Namespace namespace = thisElement.getNamespace();
        if (!namespace.equals(Namespace.NO_NAMESPACE)) {
            Namespace existingRootNamespace = 
                  rootElement.getNamespaceForPrefix(namespace.getPrefix());
            if (existingRootNamespace == null) {
                rootElement.add(namespace);
            }
            thisElement.remove(namespace);
        }
    }
    for (Element child : (List<Element>) thisElement.elements()) {
        moveNameSpacesToRootElement(child, rootElement);
    }
}

О, я только что понял, что вам нужны атрибуты, а не элементы. Однако, это изменение тривиально, поэтому я оставлю это для вас.

0 голосов
/ 24 мая 2011

В JAXB, по крайней мере, нет документированной функции, позволяющей контролировать, к какому элементу следует добавить объявление префикса пространства имен. Однако вы должны знать, что эти два фрагмента XML семантически идентичны (не имеет значения, объявлен ли префикс пространства имен на том же узле или у какого-либо предка), поэтому вы должны решить исправить испорченный клиентский код или получить кого-то с контролем код клиента, чтобы исправить это.

...