我使用SimpleXML将XML解析为Java对象,但我无法解析此文件:
<pets>
<cats>
<cat id="0" talk="miaou" />
<cat id="1" talk="MIWAOUHAUOHou" />
</cats>
<dogs>
<dog id="0"/>
</dogs>
<mine>
<cat ref="1"/>
</mine>
</pets>
使用此Java类:
@Default
@Root(name = "pets")
public class SimpleIds
{
@ElementList(required = false)
public ArrayList<Cat> cats;
@ElementList(required = false)
public ArrayList<Dog> dogs;
@Root(name = "cat")
public static class Cat
{
@Attribute
public String talk;
public void talk()
{
System.out.println(talk);
}
}
@Root(name = "dog")
public static class Dog
{
}
@Element
public Mine mine;
@Root(name = "mine")
public static class Mine
{
@Element
public Cat cat;
}
}
这个Serializer:
Strategy strategy = new CycleStrategy("id", "ref");
Serializer serializer = new Persister(strategy);
SimpleIds xml = serializer.read(SimpleIds.class, new File("simpleIds.xml"));
xml.mine.cat.talk();
它让我不高兴:
org.simpleframework.xml.strategy.CycleException: Element '0' already exists
使用SimpleXML这种xml文件是不可能的?或者它只是一个糟糕的xml格式?
修改:如果我将cat id="0"
更改为cat id="2"
,那就像魅力一样......
答案 0 :(得分:1)
在CycleStrategy的构造函数中,您可以传入参数以指定是否使用“id”作为identitfy元素或其他内容的属性。这里引起异常是因为它注意到两个具有相同“id”的元素。试试这个
CycleStrategy s = new CyctleStragegy("myid", "myreference")
它会起作用。
答案 1 :(得分:0)
您的XML非常完美。我不知道Simple Framework但我已经完成了JAXB。
如果它有帮助,我已经使用过JAXB。
这是完美的例子。
@XmlRootElement(name ="cat")
@XmlAccessorType(XmlAccessType.FIELD)
public class Cat {
private String catName;
private int id;
Getters And Setters
}
@XmlRootElement(name ="dog")
@XmlAccessorType(XmlAccessType.FIELD)
public class Dog {
private String dogName;
private int id;
Getters And Setters
}
@XmlRootElement(name = "cats")
@XmlAccessorType(XmlAccessType.FIELD)
public class Cats {
@XmlElement(name = "cat")
private List<Cat> cats;
Getters And Setters
}
@XmlRootElement(name = "dogs")
@XmlAccessorType(XmlAccessType.FIELD)
public class Dogs {
@XmlElement(name = "dog")
private List<Dog> dogs;
Getters And Setters
}
@XmlRootElement(name ="pets")
@XmlAccessorType(XmlAccessType.FIELD)
public class Pet {
@XmlElement
private Dogs dogs;
@XmlElement
private Cats cats;
Getters And Setters
}
我测试过它请测试一下。
答案 2 :(得分:0)
最后我在W3C Recommendation找到了答案:
文档中“ID”类型的所有属性的值(包括所有xml:id属性)唯一。
这意味着我的输入XML 不正确。
我无法改变它,因为我从软件中收到它但我必须在阅读之前格式化它(并反向写回来)以获得类似这样的内容:
<pets>
<cats>
<cat id="cat-0" talk="miaou" />
<cat id="cat-1" talk="MIWAOUHAUOHou" />
</cats>
<dogs>
<dog id="dog-0"/>
</dogs>
<mine>
<cat ref="cat-1"/>
</mine>
</pets>
编辑:以下代码可以在SimpleXML中为您自动完成这些操作:
/*
* Copyright (C) 2014, Mathieu Lavigne <bludwarf@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package org.simpleframework.xml.strategy;
import static org.simpleframework.xml.strategy.Name.*;
import java.util.Map;
import org.simpleframework.xml.core.Persister;
import org.simpleframework.xml.stream.Node;
import org.simpleframework.xml.stream.NodeMap;
/**
* CycleStrategy for SimpleXML allowing having duplicate IDs on nodes from different types.
*
* <p>Known limitations : </p>
*
* <ul>
* <li>as for Legacy CycleStrategy, new ids are generated for <b>every node</b> when calling {@link Persister#write(Object, java.io.File)}
* </ul>
*
* @author bludwarf@gmail.com
* @since 26 juin 2014
*/
public class TypedCycleStrategy extends CycleStrategy
{
private String mark;
private String refer;
public TypedCycleStrategy()
{
this(MARK, REFER, LABEL, LENGTH);
}
public TypedCycleStrategy(String mark, String refer)
{
this(mark, refer, LABEL, LENGTH);
}
public TypedCycleStrategy(String mark, String refer, String label)
{
this(mark, refer, label, LENGTH);
}
public TypedCycleStrategy(String mark, String refer, String label, String length)
{
super(mark, refer, label, length);
this.mark = mark;
this.refer = refer;
}
public Value read(Type type, NodeMap node, Map map)
throws Exception
{
// Unique id
makeUniqueAttribute(mark, node, type);
// Unique ref
makeUniqueAttribute(refer, node, type);
return super.read(type, node, map);
}
/**
* @param attribute mark OR refer
* @param node current node
* @param type node type
* @return the uniqueId created
* @throws Exception
*/
public static String makeUniqueAttribute(String attribute, NodeMap node, Type type) throws Exception
{
final Node entry = node.remove(attribute);
String uniqueId = null;
// Attribute found ?
if (entry != null)
{
// Replace it to make it unique
final String id = entry.getValue();
uniqueId = type.getType().getName() + "-" + id;
node.put(attribute, uniqueId);
}
return uniqueId;
}
}
注意:不要更改包裹声明!
相应的Serializer:
Strategy strategy = new TypedCycleStrategy("id", "ref");
Serializer serializer = new Persister(strategy);
SimpleIds xml = serializer.read(SimpleIds.class, new File("simpleIds.xml"));
xml.mine.cat.talk();