JAXB отображает XML-элементы с текстом, чередующимся с вложенными элементами

#java #annotations #jaxb

#java #аннотации #jaxb

Вопрос:

Я хочу, чтобы некоторые элементы отображались с текстом, а также принимали элементы, которые будут отображаться внутри них, как указано в желаемом выводе. Как мы достигаем этого, используя аннотации JAXB?

 @XmlRootElement
public class Notifications{
    private String subMsg;
    private String ccNUm;
    private String bodyMsg;
    private String paymentInfo;
    private String returnStatus;
}
  

Желаемый вывод XML

 <notifications>
    <sub_msg>
        credit card charge back <creditcard_no>3646</creditcard_no>
    </sub_msg>
    <body_msg>
        Payment of <payment_amount> $12.00 </payment_amount>
        has been <return_status> Charged back </return_staus> to us
    </body_msg>
</notifications>
  

С уважением,
-Anand

Комментарии:

1. Вы уверены, что хотите это сделать? Такого рода XML-дизайн в смешанном режиме просто усложняет жизнь каждому.

2. Привет, Скаффман, да. Это часть одной из моих задач, и мы хотели бы получить результат, аналогичный тому, о котором я упоминал

Ответ №1:

Я согласен со скаффманом, сначала вам нужно поискать альтернативы для этого XML в смешанном режиме.

Я написал начало решения, не полное, и его следует реорганизовать для некоторого механизма, но я уверен, что этого будет достаточно, чтобы понять мое направление

 @XmlRootElement(name="notifications")
public class Notification   {
    @XmlTransient
    public String ccNUm;
    @XmlTransient
    public String subMsg;
    @XmlAnyElement
    public List<Element> el  = Lists.newArrayList();

    public void afterUnmarshal(Unmarshaller u , Object parent) {
        for (Element e: el) {
            if ("sub_msg".equalsIgnoreCase(e.getTagName())){
                subMsg = e.getTextContent();
                Node creditCardNumberElement = e.getFirstChild().getNextSibling();
                if ("creditcard_no".equalsIgnoreCase(creditCardNumberElement.getNodeName()))
                    ccNUm = creditCardNumberElement.getTextContent(); 
            }
        } 
    }
}
  

Вот тесты:

 private Notification tested;
private String msg = "<notifications><sub_msg>credit card charge back <creditcard_no>3646</creditcard_no></sub_msg>/notifications>";
@Before 
public void setup() throws JAXBException{
    tested = () JAXBContext.newInstance(U.class).createUnmarshaller().unmarshal(new StringReader(msg));
}
@Test
public void testSubMessage(){
    assertEquals("credit card charge back 3646",tested.subMsg);
}
@Test
public void testCreditCardNum(){
    assertEquals("3646",tested.ccNUm);
}
  

ПРИМЕЧАНИЕ: Это решение не использует преимущества синтаксического анализа jaxb, кроме @XmlAnyElement
если это большинство ваших компонентов, я предлагаю найти лучшее решение или лучший дизайн 🙂