当前位置: 首页 > 知识库问答 >
问题:

xStream解析具有重复标记的XML

松茂实
2023-03-14
<Groups>
  <Products>
    <Product>
      <Name>One</Name>
    </Product>
    <Product>
      <Name>Two</Name>
    </Product>
  </Products>
  <OtherProducts>
    <Product>
      <Id>1</Id>
    </Product>
    <Product>
      <Id>2</Id>
    </Product>
  </OtherProducts>
</Groups>
@XStreamAlias("Groups")
class GroupData {
  List<Product> Products;
  List<OtherProduct> OtherProducts;
}

@XStreamAlias("Product")
class Product {
   String name;
}

@XStreamAlias("Product")
class OtherProduct {
   int id;
}

我相信一定有一些方法可以指定用来解析XML对象的类,但我无法理解XStream属性的本质或本质。

如有任何帮助,将不胜感激。

共有1个答案

解浩渺
2023-03-14

解决办法并不简单。

封送(对象到XML)是相当简单的,当您必须解封(XML到对象)它时,问题就来了。

发生的情况是,当XStream开始读取XML并找到Product标记时,它无法确定它是“Product”还是“otherproduct”对象,因为标记名是相同的。

@XStreamAlias("Product")
public class Product {

    @XStreamAlias("Name")
    private String name;

    public Product() {
    }

    public Product(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;

    }

}
@XStreamAlias("Product")
public class OtherProduct {

    @XStreamAlias("Id")
    private int id;

    public OtherProduct() {

    }

    public OtherProduct(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

}
@XStreamAlias("Groups")
public class GroupData {
    @XStreamAlias("Products")
    private List<Product> products = new ArrayList<>();

    @XStreamAlias("OtherProducts")
    private List<OtherProduct> otherProducts = new ArrayList<>();

    public void add(Product product) {
        getProducts().add(product);
    }

    public void add(OtherProduct otherProduct) {
        getOtherProducts().add(otherProduct);
    }

    public List<Product> getProducts() {
        return products;
    }

    public List<OtherProduct> getOtherProducts() {
        return otherProducts;
    }

}

ProductConverter类:

public class ProductConverter implements Converter {
    private ProductUnmarshaller productUnmarshaller = new ProductUnmarshaller();

    @Override
    public boolean canConvert(@SuppressWarnings("rawtypes") Class clazz) {
        return clazz.equals(Product.class);
    }

    @Override
    public void marshal(Object object, HierarchicalStreamWriter hsw, MarshallingContext mc) {
        Product product = (Product) object;
        hsw.startNode("Name");
        hsw.setValue(product.getName());
        hsw.endNode();
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader hsr, UnmarshallingContext uc) {
        return productUnmarshaller.unmarshal(hsr, uc);
    }

}

OtherProductConverter类:

public class OtherProductConverter implements Converter {
    private ProductUnmarshaller productUnmarshaller = new ProductUnmarshaller();

    @Override
    public boolean canConvert(@SuppressWarnings("rawtypes") Class clazz) {
        return clazz.equals(OtherProduct.class);
    }

    @Override
    public void marshal(Object object, HierarchicalStreamWriter hsw, MarshallingContext mc) {
        OtherProduct otherProduct = (OtherProduct) object;
        hsw.startNode("Id");
        hsw.setValue(Integer.toString(otherProduct.getId()));
        hsw.endNode();
    }

    @Override
    public Object unmarshal(HierarchicalStreamReader hsr, UnmarshallingContext uc) {
        return productUnmarshaller.unmarshal(hsr, uc);
    }


}

ProductUnmarsheller类:

public class ProductUnmarshaller {

    public Object unmarshal(HierarchicalStreamReader hsr, UnmarshallingContext uc) {
        hsr.moveDown();

        String nodeName = hsr.getNodeName();
        String nodeValue = hsr.getValue();

        hsr.moveUp();

        if ("Name".equals(nodeName)) {
            return new Product(nodeValue);
        } else if ("Id".equals(nodeName)) {
            return new OtherProduct(Integer.parseInt(nodeValue));
        } else {
            return null;
        }



    }

}
public class ProductTest {
    @Test
    public void test() {
        Product productOne = new Product("One");
        Product productTwo = new Product("Two");

        OtherProduct otherProduct1 = new OtherProduct(1);
        OtherProduct otherProduct2 = new OtherProduct(2);

        GroupData group = new GroupData();
        group.add(productOne);
        group.add(productTwo);
        group.add(otherProduct1);
        group.add(otherProduct2);

        XStream xs = new XStream();
        xs.processAnnotations(GroupData.class);
        xs.processAnnotations(OtherProduct.class);
        xs.processAnnotations(Product.class);
        xs.registerConverter(new ProductConverter());
        xs.registerConverter(new OtherProductConverter());
        String xml = xs.toXML(group);
        System.out.println(xml);
        GroupData gd = (GroupData) xs.fromXML(xml);

        for (Product product: gd.getProducts()) {
            System.out.println(product.getName());
        }

        for (OtherProduct otherProduct: gd.getOtherProducts()) {
            System.out.println(otherProduct.getId());
        }

    }

}
 类似资料:
  • 有谁能帮我解决这个问题吗? 干杯达安

  • 我实际上正在用Java开发一个文本解析器,有人要求我通过用它解析HTML来增强它。解析器的目的是将被解析的文件分成另外三个文件,一个包含文件中包含的所有单词,一个包括所有句子,另一个包含所有问题。 *.txt部分工作得很好,但我在解析HTML时遇到了一个问题。 我创建了一个扩展名为*.txt的临时文件,并将其在我的文本解析器中传递,但是如果我传递一个带有HTML文件链接的URL,其格式如下所示:

  • 有关于OpenNLP中解析器标记含义的文档吗?我知道POS标记类型遵循树库约定,但不幸的是,我没有找到任何关于解析器标记的信息,例如“SBAR”等。 这个留档是存在于某个地方还是我必须自己弄清楚?

  • 问题内容: 我目前使用如下所示的XML 我所坚持的是,在使用XStream时,我需要能够忽略出现的某些标签(在“ FavOS”上方的情况下),这些标签可能未知或将来会更改。有没有办法忽略所有与当前实现的不匹配的标签? (使用XStream 1.3.1) 问题答案: 由于我花了超过15分钟的时间才能找到此答案,因此我认为应该发布它。 这似乎会跳过不在您的对象中的xml项。

  • 问题内容: 我有一个HTML文档集合,我需要为其解析部分中 标记的内容。这些是我感兴趣的唯一HTML标记,即不需要在部分中解析任何内容。 我试图使用JDom提供的XPath支持来解析这些值。但是,这不能很好地解决,因为部分中的许多HTML都是无效的XML。 有人对我可能如何处理格式错误的HTML解析这些标记值有任何建议吗? 干杯,唐 问题答案: 您可能会使用Jericho HTML Parser

  • 当我运行我的应用程序时,它突然显示未解析标识符的错误。