XStream:如何在封送的XML中隐藏2个不必要的父节点?

时间:2013-12-15 23:42:14

标签: java xml marshalling testng xstream

在单元测试项目中,我需要一些帮助来弄清楚如何在封送的XML中隐藏2个不必要的父节点?任何人都可以帮我弄清楚怎么做吗?

我的marshalled output看起来像这样:

<suite>
  <suiteName>Suite 1</suiteName>
  <sauceURL>http://username-string:access-key-string@ondemand.saucelabs.com:80/wd/hub</sauceURL>
  <tests>
    <test>
      <rowArgs>
        <arg>
          <enabled type="java.lang.Boolean">true</enabled>
        </arg>
        <arg>
          <testname type="java.lang.String">Test 1</testname>
        </arg>
        <arg>
          <environment type="java.lang.String">portal1</environment>
        </arg>
        <arg>
          <testlocale type="java.lang.String">Grid</testlocale>
        </arg>
        <arg>
          <browser type="java.lang.String">Firefox</browser>
        </arg>
        <arg>
          <url type="java.lang.String">http://google.com</url>
        </arg>
      </rowArgs>
    </test>
            ...

但我想隐藏不必要的&#34; rowArgs&#34;和&#34; arg&#34;标记,以便其余节点立即位于测试节点下。我怎么能这样做?

你可以see my code HERE, if it helps帮助我。我怀疑我需要写自己的变压器?我同时也会参与那个实验。

1 个答案:

答案 0 :(得分:4)

实际上,您需要一个自定义转换器,因为它是两个嵌套的集合,您不想显示这些对象可能具有其他将被序列化的子元素。

这是XStream没有直接涵盖的情况,但可以使用自定义转换器轻松修复。

您可以在包含所有这些修改的git clone of your project中找到所有这些内容。但是,由于所有内容都应该在这里可见,我随后解释了问题的关键部分,包括一些代码示例。

我为你的项目实现了这样一个转换器。执行转换的代码是:

  @Override
  public void marshal(Object source, HierarchicalStreamWriter writer, MarshallingContext context) {
    TestRow test = (TestRow)source;
    for (TestArguments arg : test.getArguments()) {
      for (ArgObject val : arg.getAllTestArguments()) {
        writer.startNode(val.getKey());
        writer.addAttribute("type", val.getType());
        writer.setValue(val.getVal());
        writer.endNode();

      }
    }
  }

  @Override
  public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
    TestArguments testargs = new TestArguments();
    while (reader.hasMoreChildren()) {
      reader.moveDown();
      String typeval = reader.getAttribute("type");
      if (typeval.isEmpty()) {
        typeval = "null";
      }
      testargs.getAllTestArguments().add(new ArgObject(reader.getNodeName(), typeval, reader.getValue()));
      reader.moveUp();
    }
    TestRow result = new TestRow(testargs);
    return result;
  }

这将使用您在ArgConverter中定义的平面节点结构将所有ArgObjects序列化为xml。反序列化会从此数据中创建对象。

您的源代码中有两个错误阻止了反序列化:

  • XStream反序列化无法识别所有别名注释。它的根元素SuiteData存在问题(别名为套件)。为此,我在xStream.alias("suite", SuiteData.class);中向{1}}添加了一个alad到XStream对象。
  • 如果使用默认构造函数创建XMLDataHelper实例(因为您必须通过反序列化),则调用reset会将您的TestArguments成员分配给null,这会使得添加参数变得非常不可能。我修复了在重置方法(argsWrapper)中新初始化该成员变量。

据我所知,您的代码可以按预期进行序列化/反序列化。我写了一个小测试程序,以各种方式强制执行此过程,它似乎产生相同的结果:

argsWrapper = new ArrayList<ArgObject>();