【问题标题】:Convert xml string to java object : getting `details` as null?将 xml 字符串转换为 java 对象:获取“详细信息”为空?
【发布时间】:2020-01-18 10:44:48
【问题描述】:

我一直在尝试将 xml 字符串转换为 Java 对象。

有一个根标签 TV 。其中有多个字段,但我希望将整个内容作为一个字符串。

@XmlRootElement(name = "TV")
@XmlAccessorType(XmlAccessType.FIELD)
public class TV {
    @XmlElement
    public String details;
    public String getDetails() {
        return details;
    }
    public void setDetails(String details) {
        this.details = details;
    }
    @Override
    public String toString() {
        return "TV [details=" + details + "]";
    }   
}


public class XMLtoJavaObject {

    public static void main(String[] args) {
        String xmlString = "<TV version=\"0.91fn\"><channel><title>Friends</title><link>https://www.imdb.com/title/tt0108778/</link><season>2</season></channel></TV>";
        JAXBContext jaxbContext;
        try {
            jaxbContext = JAXBContext.newInstance(TV.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            TV tv = (TV) jaxbUnmarshaller.unmarshal(new StringReader(xmlString));
            System.out.println("TV" + tv);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
}

输出:

TV [details=null]

我没有将整个嵌套的 xml 作为字符串。

有人可以帮我解决我所缺少的吗?

提前致谢

【问题讨论】:

  • 我认为问题在于您的TV 类不反映您的XML 字符串。那里没有details 字段等。尝试使用和类创建Channel channel 字段。和带有title 字段的Channel 类并检查它是否解析。
  • 我不能将整个嵌套的频道标签作为一个字符串吗?
  • 在结果字符串中你还需要标签还是只需要值?您能否根据问题中的示例提供预期结果?

标签: java xml jaxb marshalling unmarshalling


【解决方案1】:

试试这个:

TV类:

@XmlRootElement(name = "TV")
@XmlAccessorType(XmlAccessType.FIELD)
public class TV {

    @XmlElement
    private Channel channel;

    public Channel getChannel() {
      return channel;
    }

    public void setChannel(Channel channel) {
      this.channel = channel;
    }

    @Override
    public String toString() {
      return "TV [channel=" + channel + "]";
    }
}

Channel类:

@XmlAccessorType(XmlAccessType.FIELD)
public class Channel {
  @XmlElement
  private String title;
  private String link;
  private String season;

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getLink() {
    return link;
  }

  public void setLink(String link) {
    this.link = link;
  }

  public String getSeason() {
    return season;
  }

  public void setSeason(String season) {
    this.season = season;
  }

  @Override
  public String toString() {
    return "Channel [title=" + title + ", link=" + link + ", season=" + season + "]";
  }

}

输出:

TVTV [channel=Channel [title=Friends, link=https://www.imdb.com/title/tt0108778/, season=2]]

现在您可以根据需要使用 Java 获取您的详细信息,例如:

tv.getChannel().getTitle();

【讨论】:

  • 不,这不是我需要的。我需要整个作为一个字符串。
  • 如何通过连接所需的值来自己构建一个`String?您的 XML 结构是否经常变化?
【解决方案2】:

另一个答案:

TV类:

@XmlRootElement(name = "TV")
@XmlAccessorType(XmlAccessType.FIELD)
public class TV {

    @XmlAnyElement
    private org.w3c.dom.Element channel;

    @Override
    public String toString() {
      return "TV [channel=" + channel + "]";
    }

    public org.w3c.dom.Element getChannel() {
      return channel;
    }

    public void setChannel(org.w3c.dom.Element channel) {
      this.channel = channel;
    }

}

然后你会得到这样的文本内容:

System.out.println("text: " +  tv.getChannel().getTextContent());

输出:

text: Friendshttps://www.imdb.com/title/tt0108778/2

请注意,它只是连接所有文本。 但是拥有Element 您可以递归地遍历所有子项并将它们与标签名称和文本值一起打印。

这是一个示例递归方法: channel 字段名称需要是 Node 类型:

....
private org.w3c.dom.Node channel;
....

private static String build(Node element) {
  final String result;
  if (element instanceof Text) {
    result = element.getNodeValue();
  } else {
    final StringBuilder sb = new StringBuilder();
    sb.append("<").append(element.getNodeName()).append(">");
    for (int i = 0; i < element.getChildNodes().getLength(); i++) {
      final Node child = element.getChildNodes().item(i);
      sb.append(build(child));
    }
    sb.append("</").append(element.getNodeName()).append(">");
    result = sb.toString();
  }
  return result;
}

这样称呼:

  System.out.println(build(tv.getChannel()));

输出:

<channel><title>Friends</title><link>https://www.imdb.com/title/tt0108778/</link><season>2</season></channel>

【讨论】:

  • +1 感谢 Zolv。这有帮助。如果 jaxb 做不到,我可能不得不使用它。但希望可以根据 JAXB 回答。
猜你喜欢
  • 2015-01-13
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 2012-07-11
  • 2011-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多