Не удается разобрать список элементов из xml

Я пытаюсь разобрать ответ мыла стандартными библиотеками javax. XML ответа будет таким

    <?xml version="1.0" encoding="UTF-8"?>
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
      <s:Header>
        <ActivityId xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics" CorrelationId="465733a9-9fb7-4287-89c5-5250d5697194">00000000-0000-0000-0000-000000000000</ActivityId>
      </s:Header>
      <s:Body>
        <BResponse xmlns="http://tempuri.org/">
          <Result xmlns:a="http://someurl.ru/">
            <a:Element>
              <a:ID>11488477</a:ID>
              <a:Name>Object 1</a:Name>
            </a:Element>
            <a:Element>
              <a:ID>11488453</a:ID>
              <a:Name>Object 2</a:Name>
            </a:Element>
          </Result>
        </BResponse>
      </s:Body>
    </s:Envelope>

и мой код доступен там http://tpcg.io/JXuwHB Что я делаю не так?

    package test;

    import java.io.ByteArrayInputStream;
    import java.util.List;

    import javax.xml.bind.*;
    import javax.xml.bind.annotation.*;
    import javax.xml.soap.*;

    @XmlRootElement ( name = "Element" )
    class Element { 
        @Override
        public String toString() {
            return "Element [id=" + id + ", name=" + name + "]";
        }

        @XmlElement ( name = "ID" )
        public int id;

        @XmlElement ( name = "Name" )
        public String name; 
    }

    @XmlRootElement ( name = "BResponse", namespace = "http://tempuri.org/" )
    class BResponse {

        @XmlElementWrapper ( name = "Result", namespace = "http://someurl.ru/" )
        @XmlElement ( name = "Element", type = Element.class )
        public List<Element> result;

    }

    public class Test {

        public static void main(String[] args) throws Exception {
                System.out.println(res);
                SOAPMessage message = MessageFactory.newInstance().createMessage(new MimeHeaders(),new ByteArrayInputStream(res.getBytes("utf-8")));
                Unmarshaller unmarshaller = JAXBContext.newInstance(BResponse.class).createUnmarshaller();
                BResponse bResponse = (BResponse)unmarshaller.unmarshal(message.getSOAPBody().extractContentAsDocument());
                for ( Element element : bResponse.result )
                    System.out.println(element);
        }   

        public static String res =
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
            "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n" + 
            "  <s:Header>\r\n" + 
            "    <ActivityId xmlns=\"http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics\" CorrelationId=\"465733a9-9fb7-4287-89c5-5250d5697194\">00000000-0000-0000-0000-000000000000</ActivityId>\r\n" + 
            "  </s:Header>\r\n" + 
            "  <s:Body>\r\n" + 
            "    <BResponse xmlns=\"http://tempuri.org/\">\r\n" + 
            "      <Result xmlns:a=\"http://someurl.ru/\">\r\n" + 
            "        <a:Element>\r\n" +
            "          <a:ID>11488477</a:ID>\r\n" + 
            "          <a:Name>Object 1</a:Name>\r\n" + 
            "        </a:Element>\r\n" + 
            "        <a:Element>\r\n" + 
            "          <a:ID>11488453</a:ID>\r\n" + 
            "          <a:Name>Object 2</a:Name>\r\n" + 
            "        </a:Element>\r\n" + 
            "      </Result>\r\n" + 
            "    </BResponse>\r\n" + 
            "  </s:Body>\r\n" + 
            "</s:Envelope>";    

    }

Я прокомментировал все элементы, как в стандартном примере, и попытался разобрать их с помощью jaxb, но unmarsheller возвращает нулевой результат.

Исключение в потоке "main" java.lang.NullPointerException в test.Test.main(Test.java:39)


person Sayfulla Koneev    schedule 20.06.2019    source источник
comment
попробовать удалить @XmlRootElement ( name = "Element" ) перед Element классом? Поскольку это не root, а BResponse есть.   -  person Qingfei Yuan    schedule 20.06.2019
comment
это не помогло   -  person Sayfulla Koneev    schedule 20.06.2019
comment
попробуйте stackoverflow.com/questions/26709562/   -  person Qingfei Yuan    schedule 20.06.2019
comment
Я не могу удалить псевдоним пространства имен в ответе мыла, потому что я получаю его не из своего приложения, и поставщик не изменит свои результаты.   -  person Sayfulla Koneev    schedule 20.06.2019


Ответы (1)


Написание правильной аннотации помогло

    @XmlRootElement( name = "Element", namespace = "http://someurl.ru/" )
    class Element { 
        @Override
        public String toString() {
            return "Element [id=" + id + ", name=" + name + "]";
        }

        @XmlElement ( name = "ID", namespace = "http://someurl.ru/" )
        public int id;

        @XmlElement ( name = "Name", namespace = "http://someurl.ru/" )
        public String name; 
    }


    @XmlRootElement ( name = "BResponse", namespace = "http://tempuri.org/" )
    class BResponse {

        @XmlElementWrapper ( name = "Result", namespace = "http://tempuri.org/" )
        @XmlElement ( name = "Element" , type = Element.class, namespace = "http://someurl.ru/" )
        public List<Element> result;

    }

и нужно создать package-info.java с содержимым

    @javax.xml.bind.annotation.XmlSchema (
        xmlns = {               
                @javax.xml.bind.annotation.XmlNs ( prefix = "", namespaceURI = "http://tempuri.org/" ),             
                @javax.xml.bind.annotation.XmlNs ( prefix = "a", namespaceURI = "http://someurl.ru/" )
        }
    )
    package test;

где описаны префиксы xml и пространства имен

person Sayfulla Koneev    schedule 21.06.2019