gpt4 book ai didi

java - xStream 解析带有重复标签的 XML

转载 作者:行者123 更新时间:2023-11-30 09:19:10 24 4
gpt4 key购买 nike

我的 XML 结构如下:

<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>

我正在尝试使用 XStream 解析它,其中包含以下类:

@XStreamAlias("Groups")
class GroupData {
List<Product> Products;
List<OtherProduct> OtherProducts;
}

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

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

问题就在这里——解析器试图使用“OtherProduct”类来转换“Product”项目。

我相信一定有某种方法可以指定用于解析 XML 对象的类,但我无法确定 XStream 属性的正反面。

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

最佳答案

解决方案并不简单。

编码(对象到 XML)非常简单,当您必须解码(XML 到对象)时就会出现问题。

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

因此,您必须教会 XStream 向前看并检查您所知道的使它们与众不同的东西。在这种情况下,内部属性“Name”和“Id”。

您可以教 XSTream 如何编写转换器。

上面的解决方案显示了如何解决问题。

产品类别:

@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);
}

}

其他产品转换器类:

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 - xStream 解析带有重复标签的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18091700/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com