I need a help in the following scenario. I have got a XML String response. In that XML response I need to extract three values. I could not achieve it. I have specified the XML response and the value I need. Also I created set of .java file using pojo one line tool.
My XML Response:
<?xml version="1.0" encoding="UTF-8"?>
<response>
<control>
<status>success</status>
<senderid>XXXXX</senderid>
<controlid>ControlIdHere</controlid>
<uniqueid>false</uniqueid>
<dtdversion>3.0</dtdversion>
</control>
<operation>
<authentication>
<status>success</status>
<userid>XXXXX1</userid>
<companyid>XXXXX</companyid>
<sessiontimestamp>2014-08-22T07:12:37-07:00</sessiontimestamp>
</authentication>
<result>
<status>success</status>
<function>readByQuery</function>
<controlid>testControlId</controlid>
<data listtype="customer" count="100" totalcount="5142" numremaining="5042">
<customer>
<name>A</name>
<id>12</id>
</customer>
<customer>
<name>A</name>
<id>12</id>
</customer>
<customer>
<name>A</name>
<id>12</id>
</customer>
</data>
</result>
</operation>
In this XML response I would need the following values
Like count=100, totalcount=5142
My object class is like this
public class Data {
private String totalcount;
private Sodocument[] sodocument;
private String numremaining;
private String count;
private String listtype;
public String getTotalcount ()
{
return totalcount;
}
public void setTotalcount (String totalcount)
{
this.totalcount = totalcount;
}
public Sodocument[] getSodocument ()
{
return sodocument;
}
public void setSodocument (Sodocument[] sodocument)
{
this.sodocument = sodocument;
}
public String getNumremaining ()
{
return numremaining;
}
public void setNumremaining (String numremaining)
{
this.numremaining = numremaining;
}
public String getCount ()
{
return count;
}
}
XMLInputFactory xif = XMLInputFactory.newFactory();
Reader reader = new StringReader(response.toString());
XMLStreamReader xsr = xif.createXMLStreamReader(reader);
JAXBContext jc = JAXBContext.newInstance(Data.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Data jb = unmarshaller.unmarshal(xsr,Data.class).getValue();
System.out.println(jb.getCount());
This is my JAXB class. For the value getCount gives me null response. Can somebody help me on fixing this?
The generated class is too long for me to paste here but here is what you can try:
1) Use freeformatter.com/xsd-generator.html to generate an xsd from your xml. Copy and paste the generated xsd to a file.
2) Use xjc (comes with jdk installation) to generate the java class. It is a command line tool and you just have to run "xjc generated.xsd" and it will generate the annotated version of your class. The generated file will be for the entire xml response - so your class will really be Response.java, not Data.java and you then can drill into the Data element and it's attributes.
Add these annotations:
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Data {
#XmlAttribute
private String totalcount;
#XmlElement
private Sodocument[] sodocument;
#XmlAttribute
private String numremaining;
#XmlAttribute
private String count;
#XmlAttribute
private String listtype;
...
But note that Sodocument[] sodocument (which should be a List!) does not match <customer>. Not sure what the model is - could it be another element as well (depending on listtype!)
Related
Sorry for the foggy title, I know it does not tell much.
Please consider the following xsd type definition:
<xsd:complexType name="TopicExpressionType" mixed="true">
<xsd:sequence>
<xsd:any processContents="lax" minOccurs="0"/>
</xsd:sequence>
<xsd:attribute name="Dialect" type="xsd:anyURI" use="required"/>
<xsd:anyAttribute/>
</xsd:complexType>
Complete XSD: http://docs.oasis-open.org/wsn/b-2.xsd
Corresponding JAXB generated Java class:
package org.oasis_open.docs.wsn.b_2;
import org.w3c.dom.Element;
import javax.xml.bind.annotation.*;
import javax.xml.namespace.QName;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "TopicExpressionType", propOrder = {
"content"
})
public class TopicExpressionType {
#XmlMixed
#XmlAnyElement(lax = true)
protected List<Object> content;
#XmlAttribute(name = "Dialect", required = true)
#XmlSchemaType(name = "anyURI")
protected String dialect;
#XmlAnyAttribute
private Map<QName, String> otherAttributes = new HashMap<QName, String>();
public List<Object> getContent() {
if (content == null) {
content = new ArrayList<Object>();
}
return this.content;
}
public String getDialect() {
return dialect;
}
public void setDialect(String value) {
this.dialect = value;
}
public Map<QName, String> getOtherAttributes() {
return otherAttributes;
}
}
The first goal is to produce an XML like this with JAXB:
<wsnt:TopicExpression Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete" xmlns:tns="http://my.org/TopicNamespace">
tns:t1/*/t3
</wsnt:TopicExpression>
Please note the followings:
The value of the TopicExpression element is basically a query string that refers to QNames. Example: tns:t1/*/t3
The value of the TopicExpression element contains one or more QName like strings (tns:t1). It must be a string as in the example, it cannot be an Element (e.g.: <my-expresseion>tns:t1/*/t3<my-expresseion/>)
The value of the TopicExpression element is an arbitrary string (at least from the schema's perspective, it follows the rules defined here: https://docs.oasis-open.org/wsn/wsn-ws_topics-1.3-spec-os.pdf page 18)
Even though the value is a string, I need to define the corresponding name space declarations. So if I have an expression like this:
tns:t1 then xmlns:tns has to be declared. If my expresseion is tns:t1/*/tns2:t3 then both xmlns:tns and xmlns:tns2 have to be declared.
The second goal is to get the value of TopicExpression on the other side together with the namespace, using JAXB.
I am completely stuck, I don't know how I could implement this. My only idea is to manually build the value for the TopicExpression and somehow tell the marshaller to include the related namespace declaration despite there is no actual element using it.
Update
Example for a complete SOAP request that includes the before mentioned TopicExpression:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
<env:Header>
<Action xmlns="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest</Action>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:57182d32-4e07-4f5f-8ab3-24838b3e33ac</MessageID>
</env:Header>
<env:Body>
<ns3:Subscribe xmlns:ns3="http://docs.oasis-open.org/wsn/b-2" xmlns:ns4="http://www.w3.org/2005/08/addressing" >
<ns3:ConsumerReference>
<ns4:Address>http://my-notification-consumer-url</ns4:Address>
</ns3:ConsumerReference>
<ns3:Filter>
<ns3:TopicExpression Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Simple" xmlns:ns5="http://my.org/TopicNamespace" xmlns:ns6="http://extension.org/TopicNamespace">
ns5:t1/*/ns6:t3
<ns3:TopicExpression/>
</ns3:Filter>
</ns3:Subscribe>
</env:Body>
</env:Envelope>
Not sure, If I have understood your requirement correctly. See if this code sample is helpful for you. If not then maybe try to edit your question a bit and make me understand what exactly you are looking for. I will try to modify and update the code accordingly. Trying with a simple example would be better than providing the complete XSD. Also, look into the following methods: beforeMarshal and afterUnmarshal.
Following is the XML I am trying to marshal and unmarshal
<tns:TopicExpression Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete" xmlns:tns="http://my.org/TopicNamespace">
tns:t1/*/t3
</tns:TopicExpression>
TopicExpressionType.class:
#Data
#XmlAccessorType(XmlAccessType.FIELD)
public class TestPojo {
#XmlValue
private String TopicExpression;
#XmlAnyAttribute
private Map<String, Object> anyAttributes = new HashMap<>();
}
Main.class:
public class Main {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("topic.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(TestPojo.class).createUnmarshaller();
final TestPojo topic = unmarshaller.unmarshal(xmlStreamReader, TestPojo.class).getValue();
System.out.println(topic.toString());
StringWriter stringWriter = new StringWriter();
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("http://my.org/TopicNamespace", "tns");
Marshaller marshaller = JAXBContext.newInstance(TestPojo.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaces);
QName qName = new QName("http://my.org/TopicNamespace","TopicExpression","tns");
JAXBElement<TestPojo> root = new JAXBElement<TestPojo>(qName, TestPojo.class, topic);
marshaller.marshal(root, stringWriter);
String result = stringWriter.toString();
System.out.println(result);
}
}
As you can see as of now I have populated the namespaces map directly. If this is dynamic then you can populate the same in a map and accordingly you can add it while marshaling.
This will provide the following output during the unmarshalling:
TestPojo(TopicExpression=
tns:t1/*/t3
, anyAttributes={Dialect=http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete})
During marshaling:
<tns:TopicExpression xmlns:tns="http://my.org/TopicNamespace" Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete">
tns:t1/*/t3
</tns:TopicExpression>
So the solution I've implemented:
Created a new TopicExpressionType class which has fields not only for the expression but for the namespaces too, used in the expression:
public class TopicExpressionType {
String dialect;
String expression;
List<Namespace> namespaces;
public TopicExpressionType(String dialect, String expression, List<Namespace> namespaces) {
this.dialect = dialect;
this.expression = expression;
this.namespaces = namespaces;
}
public static class Namespace {
String prefix;
String namespace;
public Namespace(String prefix, String namespace) {
this.prefix = prefix;
this.namespace = namespace;
}
public String getPrefix() {
return prefix;
}
public String getNamespace() {
return namespace;
}
}
}
Then implemented an XmlAdapter that is aware of the specifics, knows how to extract namespace prefixes from the expression string and it can read/write namespace declarations on the TopicExpression XML element:
public class TopicExpressionTypeAdapter extends XmlAdapter<Element, TopicExpressionType> {
#Override
public Element marshal(TopicExpressionType topicExpression) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
Element element = document.createElementNS("http://docs.oasis-open.org/wsn/b-2", "mns1:TopicExpression");
element.setAttribute("Dialect", topicExpression.getDialect());
element.setTextContent(topicExpression.getExpression());
for (var ns : topicExpression.namespaces) {
element.setAttribute("xmlns:" + ns.prefix, ns.namespace);
}
return element;
}
#Override
public TopicExpressionType unmarshal(Element arg0) throws Exception {
if (arg0.getFirstChild() instanceof Text text) {
var expression = text.getData();
if (expression == null || expression.isBlank())
throw new TopicExpressionAdapterException("Empty content");
// Extract the prefixes from the expression
var namespacePrefixes = new ArrayList<String>();
getNamespacePrefixes(expression, namespacePrefixes);
//Now get the namespaces for the prefixes
var nsMap = new ArrayList<TopicExpressionType.Namespace>();
for (var prefix : namespacePrefixes) {
var namespace = arg0.getAttribute("xmlns:" + prefix);
if (namespace == null || namespace.isBlank())
throw new TopicExpressionAdapterException("Missing namespace declaration for the following prefix: " + prefix);
nsMap.add(new TopicExpressionType.Namespace(prefix, namespace));
}
var dialect = arg0.getAttribute("Dialect");
if (dialect == null || dialect.isBlank())
throw new TopicExpressionAdapterException("Missing Dialect attribute");
return new TopicExpressionType(dialect, expression, nsMap);
} else {
throw new TopicExpressionAdapterException("Unexpected child element type: " + arg0.getFirstChild().getClass().getName());
}
}
public static class TopicExpressionAdapterException extends Exception {
public TopicExpressionAdapterException(String message) {
super(message);
}
}
}
Note: Implementation of the getNamespacePrefixes() method is left out intentionally from this answer.
The last step is to add the following annotation wherever the TopicExpressionType is used in JAXB generated classes:
#XmlJavaTypeAdapter(TopicExpressionTypeAdapter.class)
TopicExpressionType topicExpression;
In my application user uploads several XMLs. Few XMLs that are uploaded do not contain a namespace tag and others contain it. I want to be able to support upload for both. JAXB is giving exception on former.
I want to able able to make namespace as optional ie support both files.
XML that is working
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ns2:transforms xmlns:ns2="http://www.mynamesapace.com/xmlbeans/connectorconfig">
XML that is failing
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<transforms>
Here is how I am unmarshalling the XML
JAXBContext jaxbContext = JAXBContext.newInstance(Transforms.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
transforms = (Transforms) jaxbUnmarshaller.unmarshal(file);
This is my pojo
#XmlRootElement(name = "transforms", namespace =
"http://www.mynamesapace.com/xmlbeans/connectorconfig")
public class Transforms implements ConfigDiffable<Transforms,
ChangedTransforms> {
.....
Update :
If I remove
namespace =
"http://www.mynamesapace.com/xmlbeans/connectorconfig"
XML without namespace start working
Create a class:
class XMLReaderWithoutNamespace extends StreamReaderDelegate {
public XMLReaderWithoutNamespace(XMLStreamReader reader) {
super(reader);
}
#Override
public String getAttributeNamespace(int arg0) {
return "";
}
#Override
public String getNamespaceURI() {
return "";
}
}
Change your unmarshalling to:
JAXBContext jaxbContext = JAXBContext.newInstance(Transforms.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
InputStream is = new FileInputStream(file);
XMLStreamReader xsr = XMLInputFactory.newFactory().createXMLStreamReader(is);
XMLReaderWithoutNamespace xr = new XMLReaderWithoutNamespace(xsr);
transforms = (Transforms) jaxbUnmarshaller.unmarshal(xr);
I had no namespace defined in the pojo when I tested this.
Solution taken from this answer.
I write manually a KML file trying to import some polygons in MyMaps. This way works fine:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
<Placemark>
<Style>
<PolyStyle>
<color>#a00000ff</color>
<outline>0</outline>
</PolyStyle>
</Style>
<Polygon>
<outerBoundaryIs>
<LinearRing>
<coordinates>9.184254,45.443636 9.183379,45.434288 9.224836,45.431499 9.184254,45.443636</coordinates>
</LinearRing>
</outerBoundaryIs>
</Polygon>
</Placemark>
</Document>
</kml>
I try to write a java program using JAK that generate a most possibile equal file, but it doesn't work with Maps
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:kml xmlns:atom="http://www.w3.org/2005/Atom" xmlns:ns3="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:xal="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0">
<ns3:Document>
<ns3:Placemark>
<ns3:Style>
<ns3:PolyStyle>
<ns3:color>#EABCFF</ns3:color>
<ns3:outline>0</ns3:outline>
</ns3:PolyStyle>
</ns3:Style>
<ns3:Polygon>
<ns3:innerBoundaryIs>
<ns3:LinearRing>
<ns3:coordinates>9.184254,45.443636 9.183379,45.434288 9.224836,45.431499 9.184254,45.443636</ns3:coordinates>
</ns3:LinearRing>
</ns3:innerBoundaryIs>
</ns3:Polygon>
</ns3:Placemark>
</ns3:Document>
</ns3:kml>
That's program:
public static void main(String[] args) throws IOException {
// Style
PolyStyle polystyle = KmlFactory.createPolyStyle();
polystyle.setColor("#EABCFF");
// polystyle.setFill(true);
polystyle.setOutline(false);
//
Kml kml = KmlFactory.createKml();
Document document = kml.createAndSetDocument();
Placemark pm = document.createAndAddPlacemark();
LinearRing linearRing = pm.createAndSetPolygon().createAndAddInnerBoundaryIs().createAndSetLinearRing();
linearRing.addToCoordinates(9.184254, 45.443636, 0);
linearRing.addToCoordinates(9.183379, 45.434288, 0);
linearRing.addToCoordinates(9.224836, 45.431499, 0);
linearRing.addToCoordinates(9.184254, 45.443636, 0);
pm.createAndAddStyle().setPolyStyle(polystyle);
//
kml.marshal(new FileWriter("D:/prova.kml"));
}
I view <ns3: in your kml this make the kml invalid for google maps
Try to correct the file
I had the same problem.
Instead of using kml.marshal(new FileWriter("D:/prova.kml")); I did this...
String name = kml.getClass().getSimpleName();
if ("Kml".equals(name)) {
name = name.toLowerCase();
}
JAXBContext jaxbContext = JAXBContext.newInstance(Kml.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
// output pretty printed
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new NameSpaceBeautyfier());
JAXBElement<Kml> jaxbKml = new JAXBElement<>(new QName("http://www.opengis.net/kml/2.2", name), (Class<Kml>) kml.getClass(), kml);
jaxbMarshaller.marshal(jaxbKml, file);
With a NameSpaceBeautifier like this ...
private static final class NameSpaceBeautyfier extends NamespacePrefixMapper {
private static final String KML_PREFIX = ""; // DEFAULT NAMESPACE
private static final String KML_URI= "http://www.opengis.net/kml/2.2";
#Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if(KML_URI.equals(namespaceUri)) {
return KML_PREFIX;
}
return suggestion;
}
#Override
public String[] getPreDeclaredNamespaceUris() {
return new String[] { KML_URI };
}
private NameSpaceBeautyfier() {
}
}
Hope this helps..
I have a data source that has switched from base64 embedded image data to XOP image data. I'm using Java/JAXB to unmarshal the data and can't find any good sources describing how it's done. All references seem to describe doing this with SOAP messages which seem to take care of some of the heavy lifting for you.
In my case, the data is coming in effectively as a string that needs to be unmarshalled into objects created by JAXB. Since the new messages start with
Mime-Version: 1.0
Content-Type: multipart/related; start-info="text/xml"; type="application/xop+xml";
start="<-963165769043289641.1400077877224#xxxxxyyyyyy.ca>";
boundary="----=_Part_0_-338193320.1400077877317"
obviously it won't unmarshal the data as XML as it doesn't look like XML (no data allowed before prolog).
Can this be done with JAXB? The creation of the object from the schema seems to work fine and creates what looks like a proper object (it creates an Include element). I've tried creating an AttachmentUnmarshaller manually but it hasn't helped ... the incoming data is still not recognized as XML. I feel like I'm missing a fundamental step but can't find any good references or examples.
Any help would be greatly appreciated.
Below is an approach that might help.
Message
Below is roughly what you are going to be processing:
MIME-Version: 1.0
Content-Type: Multipart/Related;boundary=MIME_boundary;
...
--MIME_boundary
Content-Type: application/xop+xml;
...
<soap:Envelope ...
<soap:Body>...
<foo>
<photo xmlmime:contentType='image/png'>
<xop:Include xmlns:xop='http://www.w3.org/2004/08/xop/include'
href='cid:http://example.org/me.jpeg'/></m:photo>
...
--MIME_boundary
Content-Type: image/png
Content-Transfer-Encoding: binary
Content-ID: <http://example.org/me.png>
// binary octets for png
Demo Code
Demo
The code below assumes you have processed the message to do the following:
Extract the XML fragment
Extract the attachments and are able to key them on the cid.
import java.io.File;
import javax.xml.bind.*;
public class Demo {
private static String base64 = "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5/ooooA//2Q==";
public static void main(String[] args) throws Exception {
// Create the JAXBContext & Unmarshaller
JAXBContext jc = JAXBContext.newInstance(Foo.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
// Create a custom AttachementUnmarshaller. Populate the Map
// AttachmentUnmarshaller with the attachments keyed on the cid.
MyAttachmentUnmarshaller attachmentUnmarshaller = new MyAttachmentUnmarshaller();
attachmentUnmarshaller.getAttachments().put("cid:http://example.org/me.jpeg", DatatypeConverter.parseBase64Binary(base64));
// Set the AttachmentUnmarshaller on the Unmarshaller
unmarshaller.setAttachmentUnmarshaller(attachmentUnmarshaller);
// Unmarshal the XML piece
File xml = new File("src/forum24407360/input.xml");
Foo foo = (Foo) unmarshaller.unmarshal(xml);
}
}
MyAttachmentUnmarshaller
Below is what the AttachmentUnmarshaller looks like. An AttachmentUnmarshaller is passed in the cid and is responsible for returning the corresponding binary data. In a JAX-WS environment this is handled automatically for you, but there is nothing preventing you from doing it manually. You can find more information about it here: What's the most standard Java way to store raw binary data along with XML?.
import java.io.*;
import java.util.*;
import javax.activation.*;
import javax.xml.bind.attachment.AttachmentUnmarshaller;
public class MyAttachmentUnmarshaller extends AttachmentUnmarshaller {
private Map<String, byte[]> attachments = new HashMap<String, byte[]>();
public Map<String, byte[]> getAttachments() {
return attachments;
}
#Override
public DataHandler getAttachmentAsDataHandler(String cid) {
byte[] bytes = attachments.get(cid);
return new DataHandler(new ByteArrayDataSource(bytes));
}
#Override
public byte[] getAttachmentAsByteArray(String cid) {
return attachments.get(cid);
}
#Override
public boolean isXOPPackage() {
return true;
}
private static class ByteArrayDataSource implements DataSource {
private byte[] bytes;
public ByteArrayDataSource(byte[] bytes) {
this.bytes = bytes;
}
public String getContentType() {
return "application/octet-stream";
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(bytes);
}
public String getName() {
return null;
}
public OutputStream getOutputStream() throws IOException {
return null;
}
}
}
XML Piece
<foo>
<image>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:http://example.org/me.jpeg"/>
</image>
</foo>
I'm using SimpleXML for parsing XML files in Android. I need to parse the following XML,
<?xml version="1.0" encoding="UTF-8"?>
<Box>
<SerialNumber>XYSSDSD</SerialNumber>
<Alias><![CDATA[SSS: 8]]></Alias>
<BoxType>SD</BoxType>
</Box>
I wrote Bean class to map the above xml
#Element(name="SerialNumber")
private String serialNumber;
#Element(name="Alias", data=true)
private String aliasType;
#Element(name="BoxType")
private String boxType;
I'm getting the following exception while parsing the XML
1-24 23:57:47.407: E/Exception in APItoBEAN(1796): Unable to satisfy
#org.simpleframework.xml.Element(data=true, name=Alias, required=true,
type=void) on field 'aliasType' private .Box.aliasType for class Box
at line 1
Could you anybody help me here?
Thank you for your time!
I tested this on PC (SimpleXML 2.6.6) with following Java Code:
Box Class:
#Root
public class Box
{
#Element(name = "SerialNumber")
private String serialNumber;
#Element(name = "Alias", data = true)
private String aliasType;
#Element(name = "BoxType")
private String boxType;
// ...
}
Reading the XML:
final File f = new File("test.xml"); // your XML is in this file
Serializer ser = new Persister();
Box box = ser.read(Box.class, f);
Works without exception.
Did you clean your project and build it again? Your code seems to be OK.