RESTeasy / JAXB; как избежать добавления пространства имен в элемент тега? (Список в JAXB)
Я собираюсь упростить свои классы и выводить как можно лучше здесь, но в основном я хочу добавить org.w3c.dom.Element
(представляющий ссылку atom в этом случае) к объекту JAXB, который я возвращаю. Класс 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="". Я создаю элемент неправильным образом? Или возможно что-то еще не так? Я скорее в недоумении, почему он добавляет их вообще, поэтому любая помощь/объяснение будет оценена.
Edit: я считаю, что это должно быть связано с пространством имен документа, который я использую для создания элемента, но я не уверен, как его исправить. Есть ли способ установить (XML) targetNamespace в документе?
Edit 2: я не уверен, добавляет ли он что-нибудь полезное для кого-либо, но с большим количеством экспериментов я обнаружил, что linkTemplate.setAttribute("xmlns:" + anything, null);
имеет эффект создания ссылки с xmlns:[anything]=""
и удаление любых других, которые в противном случае были бы созданы.
Edit 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 ответов
является ли значение ATOM_LINK = "link"? если это так, это должен быть "atom:link" и удалить вызов setPrefix ().
Я считаю, что проблема в том, что 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
атрибут напрямую, somethibng ошибается.
поскольку ни одно из предложений здесь не сработало для меня, я решил пойти другим путем. В конце концов я в конечном итоге перезаписи RESTEasy слушатель добавляет Маршаллер со слушателем моих собственных. Этот прослушиватель затем вызывает прослушиватель RESTEasy (если он присутствовал), прежде чем добавлять ссылки вручную в поле RESTServiceDiscovery (вы должны получить это поле с помощью отражения и отключить проверку доступа с полем.setAccessible (true) перед получением объекта).