Resteasy / JAXB;Как избежать добавления пространства имен к элементу в теге <any>?(Список <Element>в JAXB) - PullRequest
6 голосов
/ 28 октября 2011

Я собираюсь упростить свои классы и вывод как можно лучше здесь, но в основном я хочу добавить org.w3c.dom.Element (представляющий ссылку на атом в данном случае) к объекту JAXB I ' м возвращаюсь. Класс JAXB выглядит примерно так:

import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import org.w3c.dom.Element;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "People", namespace = "main", propOrder = {
    "any",
    "persons"
})
public class People {
    @XmlAnyElement
    protected List<Element> any;
    @XmlElement(name = "person", namespace = "main")
    protected List<Person> persons;
    [...]
}

Я создаю Элемент, используя шаблон, который я создаю так:

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class ElementGen {
    public Element getTemplate() throws DOMException, SAXException, ParserConfigurationException {
        final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        final Schema schema = sf.newSchema(new StreamSource(
                Thread.currentThread().getContextClassLoader().getResourceAsStream(ATOM_XSD)));
        final DocumentBuilderFactory docBuilder = DocumentBuilderFactory.newInstance();
        docBuilder.setSchema(schema);
        final Document doc = docBuilder.newDocumentBuilder().newDocument();
        linkTemplate = doc.createElementNS(ATOM_NAMESPACE, ATOM_LINK);
        return linkTemplate;
    }
}

(На самом деле класс выглядит не так, я просто пытаюсь максимально упростить компиляцию чего-либо, чтобы протестировать его без всего внешнего беспорядка).

Затем я клонирую этот шаблон, используя linkTemplate.cloneNode(false);

Теперь все это работает в том смысле, что он возвращает xml, но странным является то, что к xml, который я получаю, присоединены дополнительные пространства имен:

<atom:link xmlns:ns3="main" xmlns="" href="href" rel="rel"/>

Если я добавлю linkTemplate.setAttribute("xmlns", null);, пространство имен "xmlns: ns3" исчезнет, ​​и я получу:

<atom:link xmlns="" href="href" rel="rel"/>

Но, похоже, нет способа удалить это xmlns = "". Я неправильно создаю Элемент? Или, может быть, что-то еще идет не так? Я скорее в растерянности, почему он вообще добавляет их, поэтому любая помощь / объяснение будет оценено.

Редактировать: Я считаю, что это должно быть связано с пространством имен документа, который я использую для генерации элемента, но я не уверен, как это исправить. Есть ли способ установить (XML) targetNamespace в документе?

Редактировать 2: Я не уверен, добавляет ли это что-нибудь полезное для кого-либо, но с большим количеством экспериментов я обнаружил, что linkTemplate.setAttribute("xmlns:" + anything, null); дает эффект создания ссылки с xmlns:[anything]="" и удаления любых других, которые были бы сгенерированы в противном случае. .

Редактировать 3: соответствующие биты xsd, используемые для генерации объектов JAXB:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0"
    xmlns="main"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:atom="http://www.w3.org/2005/Atom"
    targetNamespace="main"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified">

<xs:complexType name="People">
    <xs:sequence>
        <xs:any namespace="##other" processContents="skip" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="person" type="Person" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
    [attributes]
</xs:complexType>
[other types etc.]

Ответы [ 4 ]

0 голосов
/ 10 ноября 2011

Поскольку ни одно из предложенных здесь предложений не сработало для меня, я решил пойти другим путем. В конце концов я переписал Слушатель RESTEasy добавляет Маршаллеру с моим Слушателем. Затем этот прослушиватель вызывает прослушиватель RESTEasy (если он присутствовал) перед добавлением ссылок вручную в поле RESTServiceDiscovery (вы должны получить это поле с помощью отражения и отключить проверку доступа с помощью field.setAccessible (true) перед получением объекта) .

0 голосов
/ 02 ноября 2011

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

public class ElementGen {
   public Element getTemplate() throws DOMException, SAXException, ParserConfigurationException {
    final DocumentBuilderFactory docBuilder = DocumentBuilderFactory.newInstance();
    docBuilder.setNamespaceware(true);
    final Document doc = docBuilder.newDocumentBuilder().newDocument();
    linkTemplate = doc.createElementNS(ATOM_NAMESPACE, ATOM_LINK);
    return linkTemplate;
  }
}

Если вы обнаружите, что управляете атрибутом xmlns напрямую, что-то не так.

0 голосов
/ 04 ноября 2011

Вы пытались установить для elementFormDefault значение "Unqualified"?

0 голосов
/ 28 октября 2011

это значение ATOM_LINK = "ссылка"? если это так, это должно быть «atom: link» и удалить вызов setPrefix ().

...