I want to parse the following XML
<entry key="9" type="9">
<value>
<amount stake="10">50000000</amount>
<amount stake="1">5000000</amount>
<winner>0.0</winner>
<description>9 Correct Numbers</description>
</value>
</entry>
I try to achieve this with the follow classes:
@Root(name="entry")
public class OddsEntryXMLObject {
@Attribute(name="key")
private String iKey;
@Attribute(name="jackpot", required=false)
private String iJackpot;
@Attribute(name="type", required=false)
private String iType;
@Element(name="value")
private OddsValueXMLObject iOddsValueXMLObject;
}
public class OddsAmountXMLObject {
@Element(name="amount")
private String iAmount;
@Attribute(name="stake", required=false)
private String iStake;
}
However I get the following exception:
java.lang.RuntimeException: org.simpleframework.xml.core.ValueRequiredException: Unable to satisfy @org.simpleframework.xml.Element(data=false, name=amount, required=true, type=void) on field 'iAmount' private java.lang.String OddsAmountXMLObject.iAmount for class OddsAmountXMLObject at line 1
Anyone know how to parse this?
There is no declaration for OddsValueXMLObject
class in the code provided. Assuming the declaration is what I think it is, the error message basically means that it expects an amount
element inside an amount
element, like this:
<amount>
<amount></amount>
</amount>
Of course, there is nothing like that in the XML you have. You can parse it with this instead:
@Root(name="entry")
public class OddsEntryXMLObject{
@Attribute(name="key")
private String key;
@Attribute(name="jackpot", required=false)
private String jackpot;
@Attribute(name="type", required=false)
private String type;
@Element(name="value")
private OddsValueXMLObject value;
}
@Root(name="value")
public class OddsValueXMLObject{
@ElementList(inline=true)
private java.util.List<OddsAmountXMLObject> amounts;
@Element(name="winner", required=false)
private String winner;
@Element(name="description", required=false)
private String description;
}
@Root(name="amount")
public class OddsAmountXMLObject{
@Attribute(name="stake", required=false)
private String stake;
@Text
private String text;
}
Please find following working code
<?xml version="1.0" encoding="UTF-8"?>
<entry key="9" type="9">
<value>
<amount stake="10">50000000</amount>
<!- <amount stake="1">5000000</amount> -->
<!-- <winner>0.0</winner>-->
<!--<description>9 Correct Numbers</description> -->
</value>
</entry>
1) I have commented amount since its same attribute so throwing error , you need to fix your sample xml.
2) winner and description is missing in your class.
3) you need to define one more class to get value .
4) Your Root element is missing**
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
@Root(name="amount")
class OddsAmountXMLObject {
@Element(name="amount")
private String iAmount;
@Attribute(name="stake", required=false)
private String iStake;
}
other class
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
@Root(name="entry")
public class OddsEntryXMLObject {
@Attribute(name="key") String iKey;
@Attribute(name="jackpot", required=false)
private String iJackpot;
@Attribute(name="type", required=false)
private String iType;
@Element(name="value")
private OddsAmountXMLObject iOddsValueXMLObject;
}
Test example
import java.io.File;
import org.simpleframework.xml.core.Persister;
public class ParseExample {
public static void main(String[] list) throws Exception {
Persister persister = new Persister();
File file = new File("C:\\Users\\290008812\\Jhipster_workspace\\Test\\src\\DOMParserDemo\\NewFile.xml");//My xml path
OddsEntryXMLObject example = persister.read(OddsEntryXMLObject.class, file);
//System.out.println(example.iKey);
//System.out.println(example.amount2);
persister.write(example, System.out);
}
}
I am using "simple-xml-2.6.jar"
Result :
Since you have declared amount two time in xml getting error " Element 'amount' declared twice at line 6" so need to fix your xml structure
Exception in thread "main" org.simpleframework.xml.core.PersistenceException: Element 'amount' declared twice at line 6
at org.simpleframework.xml.core.Variable$Adapter.read(Variable.java:444)
at org.simpleframework.xml.core.Variable$Adapter.read(Variable.java:422)
at org.simpleframework.xml.core.Composite.readVariable(Composite.java:679)
at org.simpleframework.xml.core.Composite.readInstance(Composite.java:627)
There are several amount
elements so that indicates there is a list. This solution uses the javax.xml classes instead of the third party SimpleXml library. The entry
class:
@XmlRootElement(name="entry")
public class OddsEntryXMLObject {
@XmlAttribute(name="key")
private String iKey;
@XmlAttribute(name="jackpot", required=false)
private String iJackpot;
@XmlAttribute(name="type", required=false)
private String iType;
@XmlElement(name="value")
private OddsValueXMLObject value;
}
This holds a value class, though you can change this to a List
if you want:
@XmlRootElement(name="value")
public class OddsValueXMLObject {
@XmlElement(name="amount")
List<OddsAmountXMLObject> amounts;
@XmlElement(name="winner")
private String dWinner;
@XmlElement(name="description")
private String sDescription;
}
This holds an amount
class, with a List
of amounts.
@XmlRootElement(name="amount")
public class OddsAmountXMLObject {
@XmlValue
private String iAmount;
@XmlAttribute(name="stake")
private String iStake;
}
You can test it with this code:
JAXBContext jc = JAXBContext.newInstance( OddsEntryXMLObject.class, OddsValueXMLObject.class, OddsAmountXMLObject.class );
Unmarshaller u = jc.createUnmarshaller();
JAXBElement<OddsEntryXMLObject> o = u.unmarshal( new StreamSource(getClass().getResourceAsStream("SimpleXML.xml")), OddsEntryXMLObject.class);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(o, System.out);
Which outputs the same xml as the input. These classes will also do a roundtrip using schemagen
to create a .xsd
file and xjc
to compile the .xsd
schema back to Java POJOs. After the roundtrip this field names will change because the annotations don't match original names, hence it is advised that you change the field (property) names to match the annotations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.