Можно ли получить DOM Attr для атрибута, используя JAXB? - PullRequest
1 голос
/ 01 июня 2011

Мы используем JAXB для демаршаллизации фрагмента XML, который выглядит примерно так:

<someRandomElement xmlns:foo="http://example.com/foo" xpath="//foo:bar" />

Наша объектная модель:

@XmlRootElement(name="someRandomElement")
class SomeRandomClass {

    @XmlAttribute(name="xpath")
    private XPathFragment _expression;
}

class XPathFragment {
    String _expr;

    // we need this to look up namespace prefixes used in _expr
    Node _parentNode;
}

Итак, мой вопрос, какМогу ли я демонтировать XPathFragment из XML с помощью JAXB?

Я пытался использовать пользовательский XmlAdapter для XPathFragment, но, похоже, у него нет возможности доступа к DOM-узлам, соответствующим someRandomElement и его атрибутам.

Ответы [ 2 ]

2 голосов
/ 02 июня 2011

Вы можете использовать возможность передавать инициализированный XmlAdapter размагничающему.

XPathFragmentAdapter

import javax.xml.bind.annotation.adapters.XmlAdapter;

import org.w3c.dom.Document;

public class XPathFragmentAdapter extends XmlAdapter<String, XPathFragment>{

    private Document document;

    public XPathFragmentAdapter() {
    }

    public XPathFragmentAdapter(Document document) {
        this.document = document;
    }

    @Override
    public XPathFragment unmarshal(String v) throws Exception {
        XPathFragment xPathFragment = new XPathFragment();
        xPathFragment.set_expr(v);
        xPathFragment.set_parentNode(document.getDocumentElement());
        return xPathFragment;
    }

    @Override
    public String marshal(XPathFragment v) throws Exception {
        return v.get_expr();
    }

}

Демо

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;

public class Demo {

    public static void main(String[] args) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        File file = new File("input.xml");
        Document document = db.parse(file);

        JAXBContext jc = JAXBContext.newInstance(SomeRandomClass.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        unmarshaller.setAdapter(new XPathFragmentAdapter(document));
        SomeRandomClass src = (SomeRandomClass) unmarshaller.unmarshal(document);

        System.out.println(src.get_expression().get_parentNode() != null);
    }

}

SomeRandomClass

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name="someRandomElement")
class SomeRandomClass {

    private XPathFragment _expression;

    @XmlAttribute(name="xpath")
    @XmlJavaTypeAdapter(XPathFragmentAdapter.class)
    public XPathFragment get_expression() {
        return _expression;
    }

    public void set_expression(XPathFragment _expression) {
        this._expression = _expression;
    }

}

XPathFragment

import javax.xml.bind.annotation.XmlTransient;

import org.w3c.dom.Node;

class XPathFragment {
    String _expr;

    // we need this to look up namespace prefixes used in _expr
    Node _parentNode;

    public String get_expr() {
        return _expr;
    }

    public void set_expr(String _expr) {
        this._expr = _expr;
    }

    @XmlTransient
    public Node get_parentNode() {
        return _parentNode;
    }

    public void set_parentNode(Node _parentNode) {
        this._parentNode = _parentNode;
    }

}
0 голосов
/ 02 июня 2011

Для JAXB RI:

Написать пользовательский XmlAdapter для вашего XPathFragment.Вы можете получить доступ к текущему контексту пространства имен во время демаршаллинга через UnmarshallingContext.getInstance().Посмотрите, как реализована обработка QName (проверьте реализации com.sun.xml.bind.v2.model.runtime.RuntimeBuiltinLeafInfo).Для синтаксического анализа QName также необходимо разрешение пространства имен, как и у вас XPathFragment case.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...