6

I'm trying to put JAXB annotations on POJO to produce following JSON (via moxy):

{
    "apartmentNumber": "404",
    "city/town": "SomeCity",
    "state/province": "NoState",
    "street": "1st Street"
}

Some fields contains slashes. When I'm trying to put annotation @XmlElement(name="city/town")

@XMLRootElement
public class SubscriberAddress {
    private String street;
    private String apartmentNumber;

    @XMLElement(name="city/town")
    private String city;

    @XMLElement(name="state/province")
    private String state;
}

moxy treats such names as XPaths and creates following JSON

{
     "apartmentNumber" : "404",
     "city" : {
         "town" : "SomeCity"
     },
     "state" : {
         "province" : "NoState"
     },
     "street" : "1st Street"
}

Is there any way to escape slash / forbid moxy to treat slashes in element names?

stborod
  • 533
  • 4
  • 11
  • I could only guess but could you try to use a backslash? Eg: @XMLElement(name="city\\/town") as I remember somewhere in JSON documentation I saw something similar. If it works I'll post it as answer. :) – Hash Jul 18 '16 at 09:01
  • Unortunatelly, it doesn't work. It just creates entity "city\" and subentity "town". I also tried escaping like "city//town" and some more. – stborod Jul 18 '16 at 14:07
  • And have you tried just \/ ? (And not \\/ ?) – Jan-Willem Gmelig Meyling Jul 18 '16 at 16:56
  • Yeap. Leads to "Invalid escape sequence" error in eclipse. – stborod Jul 19 '16 at 18:25
  • 1
    Tried using HTML entities? Try placing / Using slashes should cause trouble with XML, which jaxb was initially designed for. So you are entering a gray area here, I guess. – RoyB Jul 20 '16 at 14:43
  • This cannot work, as / cannot be used in a valid XML element name. If your purpose is to produce JSON, maybe you should try another way (e.g. Jackson). – cdelmas Jul 21 '16 at 12:40
  • @RoyB: Yeah, I tried that. Rendered just as &47; – stborod Jul 21 '16 at 15:29
  • @cdelmas: this is allowed (I referenced to http://stackoverflow.com/questions/539143/xml-entity-for). Moreover, when I marshall object to xml, it produces entity without any problems. – stborod Jul 21 '16 at 15:31
  • @stborod maybe you can, but the xml is not valid. – cdelmas Jul 22 '16 at 09:18
  • Using slashes in your node name is allowed, but it is not the proper way. reinventing the wheel leads often to issues like yours :) – alex Jul 23 '16 at 06:40
  • @dit. I agree. I don't think slashes in node names is a good idea. But this is part of external api I should use, so I don't have a choice :) – stborod Jul 23 '16 at 10:50
  • In any way, My position is when you write provider and you say "We can handle both xml and json" you should correctly handle valid cases. Since slashes in json doesn't have any special meaning, you should handle this. But I don't see this here and I'm confused in a way "Proper instrument should work properly. This means I do smth wrong". In custody I want to say I think this is a bug with handling XMLElement and XPath annotations. Looks like moxy tries to parse xpath inside XMLElement when it shouldn't. – stborod Jul 23 '16 at 10:57

1 Answers1

1

Instead of moxy U may try GSON, as it is producing the result.

The POJO is :

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class SubscriberAddress {
    private String street;
    private String apartmentNumber;

    @XmlElement(name = "city/town")
    private String city;

    @XmlElement(name = "state/province")
    private String state;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getApartmentNumber() {
        return apartmentNumber;
    }

    public void setApartmentNumber(String apartmentNumber) {
        this.apartmentNumber = apartmentNumber;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

The JSON generated is :

{
  "SubscriberAddress": {
    "street": "Demo Street",
    "apartmentNumber": "Demo Apartment",
    "city/town": "Demo City",
    "state/province": "Demo State"
  }
}