【问题标题】:XStream - Parsing nested elements (Skipping parent)XStream - 解析嵌套元素(跳过父级)
【发布时间】:2015-08-18 17:20:13
【问题描述】:

我尝试使用 XStream 解析以下 XML。问题是,在我到达<Keywords>...</Keywords> 元素之前,一切正常。

我想获取所有 <KEYWORD> 元素,而不必创建一个类来处理 <KEYWORDS>

Sample.XML

<CATALOG>
  <PRODUCTS>
    <PRODUCT>
      <PRODUCTOID>123</PRODUTOID>
      <PRODUCTNAME>TEST NAME</NOMEPRODUTO>
      <DESCRIPTION>TEST DESCRIPTION</DESCRIPTION>
      <KEYWORDS>
        <KEYWORD>keyword_1</KEYWORD>
        <KEYWORD>keyword_2</KEYWORD>
        <KEYWORD>keyword_3</KEYWORD>
        <KEYWORD>keyword_n</KEYWORD>
      <KEYWORDS>
    </PRODUCT>
  </PRODUCTS>
</CATALOG>

目录.java

@XStreamAlias("CATALOG")
public class Catalog {

    @XStreamAlias("PRODUCTS")
    private List<Product> products;

   // Getters and Setters

}

Products.java

@XStreamAlias("PRODUCT")
public class Product {

    @XStreamAlias("PRODUCTID")
    private String id;

    @XStreamAlias("PRODUCTNAME")
    private String name;

    @XStreamAlias("DESCRIPTION")
    private String description;


   // @XStreamImplicit(itemFieldName = "KEYWORD")
   // the above line works, *IF* I delete the parent node `<KEYWORDS>`,
   // but that's not the case, I have to deal with it  

   // @StreamAlias("KEYWORDS/KEYWORD")
   // this doesn't work

   @StreamAlias("KEYWORDS")
   // and this returns the error I'm posting below after this class
   private List<String> keywords;

   // Getters and Setters

}

XStreamTest.java

public class XStreamTest {

    public static void main(String[] args) {

    String filepath = "Sample.xml";

    try {
        FileReader reader = new FileReader(filepath);
        XStream xstream = new XStream();

        xstream.processAnnotations(Catalog.class);
        xstream.processAnnotations(Product.class);

        Catalog catalog = (Catalog) xstream.fromXML(reader);
        System.out.println(catalog.getProducts().get(0).getKeywords().get(0));
    }

    catch (FileNotFoundException e) {
        e.printStackTrace();
    }

}

使用当前设置,这就是我得到的(我知道为什么会得到这个……我没有将元素 &lt;KEYWORD&gt; 映射到任何地方。

但我真的不想想创建另一个类,说“Keyword.java”只是为了处理 &lt;KEYWORDS&gt;(就像我在管理 &lt;PRODUCT&gt; 元素中的元素一样。

有没有我可以解决这个问题(不必再上课)?

Exception in thread "main" com.thoughtworks.xstream.converters.ConversionException: KEYWORD: KEYWORD
---- Debugging information ----
message             : KEYWORD
cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
cause-message       : KEYWORD
class               : java.util.ArrayList
required-type       : java.util.ArrayList
converter-type      : com.thoughtworks.xstream.converters.collections.CollectionConverter
path                : /CATALOG/PRODUCTS/PRODUCT/KEYWORDS/KEYWORD
line number         : 9
class[1]            : obscured_package.model.Product
converter-type[1]   : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
class[2]            : obscured_package.model.Catalog
version             : 1.4.8
-------------------------------
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:480)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:412)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:263)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:71)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:98)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:91)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:85)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:80)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshallField(AbstractReflectionConverter.java:480)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:412)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:263)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:65)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
    at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1206)
    at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1190)
    at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1061)
    at br.com.multiplusfidelidade.ecommerce.netshoes.batch.App.main(App.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: com.thoughtworks.xstream.mapper.CannotResolveClassException: PALAVRA
    at com.thoughtworks.xstream.mapper.DefaultMapper.realClass(DefaultMapper.java:79)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass(DynamicProxyMapper.java:55)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass(PackageAliasingMapper.java:88)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass(ClassAliasingMapper.java:79)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.ArrayMapper.realClass(ArrayMapper.java:74)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.SecurityMapper.realClass(SecurityMapper.java:71)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.MapperWrapper.realClass(MapperWrapper.java:30)
    at com.thoughtworks.xstream.mapper.CachingMapper.realClass(CachingMapper.java:47)
    at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType(HierarchicalStreams.java:29)
    at com.thoughtworks.xstream.converters.collections.AbstractCollectionConverter.readItem(AbstractCollectionConverter.java:70)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.addCurrentElementToCollection(CollectionConverter.java:98)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:91)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.populateCollection(CollectionConverter.java:85)
    at com.thoughtworks.xstream.converters.collections.CollectionConverter.unmarshal(CollectionConverter.java:80)
    at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
    ... 35 more

Process finished with exit code 1

提前致谢!

【问题讨论】:

    标签: java xml xml-parsing xstream


    【解决方案1】:

    我猜如果你现在有“关键字”的地方有“字符串”,那么你的 XML 会被正确解析。所以我猜你的问题已经在这里回答了:aliasing-contents-of-a-set-using-xstream

    您可以尝试XStreamAliasType 使用注释来完成。

    【讨论】:

    • 问题是:它是一个真实的应用程序,其中输入 XML 就像我编写的示例一样,我没有选择将其设置为“关键字”所在的“字符串”。而且我真的很想避免使用 String.replace 来更改 String....
    • 这就是为什么我建议您解释 xstream 以在读取“KEYWORD”时理解“String”类型。这就是链接答案对方法调用所做的事情,而链接注释(我希望)在您的数据类中所做的事情。
    • 我检查了你提到我的链接,但它与我试图做的完全相反,它是一个被序列化为 XML 的对象,我需要将一个 XML 序列化为一个对象。我确实尝试过使用 XStreamAliasType,但是没有用)...
    • 序列化或反序列化与命名关系是否起作用无关。不过,通过序列化查看生成的 XML,您可能会学到很多东西。你试过xstream.alias("KEYWORD", String.class);吗?
    • 我做到了...我明白你在说什么,是的,我确实尝试将 Bean 序列化为 XML,从而为“”元素生成 列表.看看这个:groups.google.com/forum/#!topic/xstream-user/JAgMtKfE54w我正在和 Jorg 讨论这个问题
    【解决方案2】:

    我在两个方面更改了您的代码:

    • 我在&lt;KEYWORDS&gt; 的结束标记中添加了一个“/”
    • 我添加了对 xstream.alias() 的调用,用于将“KEYWORD”映射到 String 类

    为我输出“keyword_1”:

    public static void main(String[] args) 
    {
        String xml = 
            "<CATALOG>\n"+
            "  <PRODUCTS>\n"+
            "    <PRODUCT>\n"+
            "      <PRODUCTID>123</PRODUCTID>\n"+
            "      <PRODUCTNAME>TEST NAME</PRODUCTNAME>\n"+
            "      <DESCRIPTION>TEST DESCRIPTION</DESCRIPTION>\n"+
            "      <KEYWORDS>\n"+
            "        <KEYWORD>keyword_1</KEYWORD>\n"+
            "        <KEYWORD>keyword_2</KEYWORD>\n"+
            "        <KEYWORD>keyword_3</KEYWORD>\n"+
            "        <KEYWORD>keyword_n</KEYWORD>\n"+
            "      </KEYWORDS>\n"+  // <--
            "    </PRODUCT>\n"+
            "  </PRODUCTS>\n"+
            "</CATALOG>";
        XStream xstream = new XStream();
    
        xstream.alias("KEYWORD", String.class);  // <--
        xstream.processAnnotations(Catalog.class);
        xstream.processAnnotations(Product.class);
    
        Catalog catalog = (Catalog) xstream.fromXML(xml);
        System.out.println(catalog.products.get(0).keywords.get(0));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多