在一个单元测试项目中,我需要一些帮助来弄清楚如何在编码(marshal)的XML中隐藏2个不必要的父节点?谁能帮我弄清楚该怎么做?

我的marshalled output看起来像这样:

<suite>
  <suiteName>Suite 1</suiteName>
  <sauceURL>http://username-string:[email protected]: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>
            ...

但是我想隐藏不必要的“rowArgs”和“arg”标签,以便其余节点位于测试节点的正下方。我怎样才能做到这一点?

您可以see my code HERE, if it helps您来帮助我。我怀疑我需要编写自己的变压器吗?同时,我将进行该实验。

最佳答案

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

这种情况不是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);中的XMLDataHelper这样的XStream对象添加了别名。
  • 如果使用默认构造函数创建TestArguments实例(必须通过反序列化),则调用reset将argsWrapper成员分配为null,这将使添加参数变得非常不可能。我修复了在reset方法(argsWrapper = new ArrayList<ArgObject>();)中新初始化该成员变量的问题。

  • 据我了解您的代码,它可以按预期方式进行序列化/反序列化。我编写了一个小型测试程序以各种方式强制执行此过程,并且似乎产生了相同的结果:
    public class XMLDataHelperTest {
    
      public static void main(String[] args) {
        File file = new File(System.getProperty("user.dir"), "test.xml");
        if (file.isFile()) {
          assertTrue(file.delete());
        }
    
        // write it once
        XMLDataHelper helper = new XMLDataHelper(file.getAbsolutePath());
    
        // read it once
        helper = new XMLDataHelper(file.getAbsolutePath());
        System.out.println(file);
      }
    }
    

    关于java - XStream:如何在编码(marshal)的XML中隐藏2个不必要的父节点?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20601369/

    10-11 20:50