【问题标题】:Using XStream for converting overly-complicated XML to Java Object使用 XStream 将过于复杂的 XML 转换为 Java 对象
【发布时间】:2013-12-14 12:39:04
【问题描述】:

我一直在使用 XStream 进行一些简单的 XML 转换,但我被困在了这个上。我要做的是创建一个 Java 程序来读取和调整这种 XML;

<?xml version="1.0" encoding="utf-8"?>
<actor id="id273212" PGFVersion="0.19" GSCVersion="0.10.4">
  <attributes>
    <text id="name">Actor 1c</text>
    <real id="time">0</real>
    <point id="position">
      <real id="x">0</real>
      <real id="y">0</real>
    </point>
    <size id="size">
      <real id="width">120</real>
      <real id="height">120</real>
    </size>
    <angle id="rotation">0</angle>
    <color id="color">
      <real id="red">1</real>
      <real id="green">1</real>
      <real id="blue">1</real>
      <real id="alpha">1</real>
    </color>
    <image id="image" />
    <text id="tags" />
    <boolean id="preloadArt">true</boolean>
  </attributes>
  <behaviors />
  <aspects>
    <graphics>
      <attributes>
        <boolean id="visible">true</boolean>
        <enumeration id="blendingMode">0</enumeration>
        <enumeration id="horizontalWrap">0</enumeration>
        <enumeration id="verticalWrap">0</enumeration>
        <enumeration id="horizontalAnchor">0</enumeration>
        <enumeration id="verticalAnchor">0</enumeration>
        <boolean id="flipHorizontally">false</boolean>
        <boolean id="flipVertically">false</boolean>
        <integer id="tileWidth">0</integer>
        <integer id="tileHeight">0</integer>
      </attributes>
    </graphics>
    <motion>
      <attributes>
        <point id="linearVelocity">
          <real id="x">0</real>
          <real id="y">0</real>
        </point>
        <real id="angularVelocity">0</real>
        <real id="maxSpeed">0</real>
        <boolean id="applyMaxSpeed">false</boolean>
      </attributes>
    </motion>
    <physics>
      <attributes>
        <real id="density">1</real>
        <real id="friction">3</real>
        <real id="restitution">1</real>
        <boolean id="fixedRotation">false</boolean>
        <boolean id="movable">true</boolean>
        <enumeration id="collisionShape">0</enumeration>
        <real id="drag">0</real>
        <real id="angularDrag">0</real>
      </attributes>
    </physics>
  </aspects>
</actor>

看不懂怎么办:&lt;text id="name"&gt;Actor 1c&lt;/text&gt;

我能得到的最接近的是:

  <text id="name">
    <variables>Actor 1c</variables>
  </text>

我所做的是,我创建了一个“文本”类,它接受一个字符串(“Actor 1c”)到“变量”中。

我尝试使用“addImplicitCollection”,但它不起作用。我知道这个问题没有简单的答案,但我应该如何构建我的 Java 以便我可以读取这些 XML 文件?

【问题讨论】:

  • 下面是如何使用 @XmlValue 将其与 JAXB 映射:blog.bdoughan.com/2011/06/…
  • @Blaise Doughan 我还是不明白。你在那里描述的就像使用xstream.useAttributeFor(PhoneNumber.class, "type"); 我已经能够做到这一点。当我在 PhoneNumber 中有类似 Text text1 = new Text(); 的内容时,我无法将其打印出来。

标签: java xml xstream


【解决方案1】:

对我来说,这里最难的部分是&lt;attributes&gt; 的映射,它可以存储复杂的对象。在 Java 中,这看起来是对象的 HashMap。现在,您的属性具有 id,这将是该哈希映射条目的键。这意味着您很可能需要为您的 XML 节点定制转换器。

根据我处理此类文档的经验,它的效率并不高,我总是最终研究 XML 工具的实现细节以了解它为什么不起作用。另一个问题是 XML 文档的某些部分可能会变得有创意,尤其是在没有模式的情况下,这不是工具非常欢迎的。

所以我建议尝试使用 StAX 解析器来解析它 - 遍历树并手动转换节点。或者将其转换为 DOM 树,然后将 DOM 树转换为对象。

【讨论】:

    【解决方案2】:

    XStream 的ToAttributedValueConverter 可以在这里为您提供帮助:

    @XStreamConverter(value=ToAttributedValueConverter.class, strings={"value"})
    @XStreamAlias("text")
    public class Text {
      private String value;
      private String id;
    
      // getters/setters/etc. as appropriate
    }
    

    以“strings”命名的字段将用于存储元素的文本内容,其他字段映射到属性。

    【讨论】:

    • 你能告诉我更多细节吗?我应该构建 -> public ToAttributedValueConverter(Class type, Mapper mapper, ReflectionProvider reflectProvider, ConverterLookup lookup, String valueFieldName)
    • @canberk 你不需要构建任何东西,ToAttributedValueConverter 是一个标准的 XStream 类,在你的类上添加 @XStreamConverter 注释应该足以激活它。与往常一样,当您使用基于注释的配置进行阅读时,您还需要调用xstream.processAnnotations(Text.class)(对于您已注释的任何其他类也是如此)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    • 1970-01-01
    • 2014-12-01
    • 1970-01-01
    相关资源
    最近更新 更多