Wrap XML Element wth text using Java? - java

I want to transform XML like this:
<account>Wally World</account>
<city>Anywhere</city>
<state>CA</state>
Into this by wrapping each element with equals and single quote i.e. =''
<account>='Wally World'</account>
<city>='Anywhere'</city>
<state>='CA'</state>
Need to transform all the element text in large XML files using Java, maybe with XSLT?

In XSLT it could be something like this:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="account|city|state">
<xsl:element name="{local-name(.)}">
<xsl:text disable-output-escaping="yes">=&apos;</xsl:text>
<xsl:value-of select="text()"/>
<xsl:text disable-output-escaping="yes">&apos;</xsl:text>
</xsl:element>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Note that it will only change account, city and state elements, and leave all other elements intact. So a document like this:
<items>
<item>
<account>Wally World</account>
<city>Anywhere</city>
<state>CA</state>
</item>
</items>
... would change into this:
<items>
<item>
<account>='Wally World'</account>
<city>='Anywhere'</city>
<state>='CA'</state>
</item>
</items>

If you want to just use SAX to make this type of simple change, here is the code:
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLFilterImpl;
import org.xml.sax.helpers.XMLReaderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class XMLPipeline {
public static void main(String[] args) throws Exception {
String inputFile = "a.xml";
PrintStream outputStream = System.out;
new XMLPipeline().process(inputFile, outputStream);
}
//default JDK
public void process(String inputFile, OutputStream outputStream) throws
SAXException, ParserConfigurationException, IOException, TransformerException {
StreamResult xwriter = new StreamResult(outputStream);
XMLReader xreader = XMLReaderFactory.createXMLReader();
XMLAnalyzer analyzer = new XMLAnalyzer(xreader);
TransformerFactory stf = SAXTransformerFactory.newInstance();
SAXSource ss = new SAXSource(analyzer, new InputSource(inputFile));
stf.newTransformer().transform(ss, xwriter);
}
public static class XMLAnalyzer extends XMLFilterImpl {
private Set<String> tags = new HashSet<String>(Arrays.asList("account", "city", "state"));
boolean bufferText = false;
StringBuilder buffer;
public XMLAnalyzer(XMLReader xmlReader) {
super(xmlReader);
}
#Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
super.startElement(uri, localName, qName, atts);
if (tags.contains(localName)) {
buffer = new StringBuilder("='");
bufferText = true;
}
}
#Override
public void characters(char[] chars, int i, int i1) throws SAXException {
if (bufferText) {
buffer.append(chars, i, i1);
} else {
super.characters(chars, i, i1);
}
}
#Override
public void endElement(String s, String s1, String s2) throws SAXException {
if (bufferText) {
buffer.append('\'');
super.characters(buffer.toString().toCharArray(), 0, buffer.length());
bufferText = false;
}
super.endElement(s, s1, s2);
}
}
}

Related

How to programmatically fix an XML document based on maxLength restrictions in the schema

How can I programmatically fix the content of an XML document to conform with the maxLength restrictions of its schema (in this case: cut the content to 10 characters if longer)?
This very similar question asks how to insert default values based on the schema (unfortunately the answer was not detailed enough for me).
The API documentation of ValidatorHandler says:
ValidatorHandler checks if the SAX events follow the set of
constraints described in the associated Schema, and additionally it
may modify the SAX events (for example by adding default values, etc.)
I looked at usages of Schema.newValidatorHandler() and ValidatorHandler.setContentHandler() on tabnine.com, but I couldn't find any examples that modify the input stream.
Example Schema:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="10" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:schema>
Example XML document:
<?xml version="1.0" encoding="UTF-8" ?>
<a xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="schema.xsd">0123456789x</a>
Example validation error:
cvc-maxLength-valid: Value '0123456789x' with length = '11' is not facet-valid with respect to maxLength '10' for type '#AnonType_a'.
Current attempts (this code uses the javax.xml APIs, but I am open to any solution at all):
import java.io.File;
import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import javax.xml.validation.ValidatorHandler;
public class Test {
public static void main(String[] args) throws Exception {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new File("schema.xsd"));
// validation
Validator validator = schema.newValidator();
validator.validate(new StreamSource(new File("document.xml")));
// modify stream while parsing?
ValidatorHandler validatorHandler = schema.newValidatorHandler();
validatorHandler.setErrorHandler(?);
validatorHandler.setContentHandler(?);
validatorHandler.setDocumentLocator(?);
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
saxParser.parse(new File("document.xml"), ?); // only accepts DefaultHandler or HandlerBase
}
}
I managed to implement a solution based on Schema.newValidatorHandler(). I lost most time with the fact that SaxParser.parse() only accepts a DefaultHandler. To insert a custom ContentHandler, one has to use SaxParser.getXMLReader().setContentHandler().
I am aware that this proof of concept is not very robust, because it is parsing the validation error message to extract the maxLength schema information. So this solution is relying on a very specific SAX implementation.
I looked at schema aware XSLT transformation, but could not find any indication that the schema information can be accessed in the transformation expressions.
Writing my own specialized schema parser is still not completely off the table.
import java.io.IOException;
import java.io.StringReader;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.XMLConstants;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.ValidatorHandler;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class TestFixMaxLength {
public static void main(String[] args) throws Exception {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new StreamSource(TestFixMaxLength.class.getResourceAsStream("schema.xsd")));
// validation on original input should fail
// schema.newValidator().validate(new StreamSource(TestFixMaxLength.class.getResourceAsStream("input.xml")));
CustomContentHandler customContentHandler = new CustomContentHandler();
ValidatorHandler validatorHandler = schema.newValidatorHandler();
validatorHandler.setContentHandler(customContentHandler);
validatorHandler.setErrorHandler(customContentHandler);
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
SAXParser saxParser = saxParserFactory.newSAXParser();
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(validatorHandler);
xmlReader.parse(new InputSource(TestFixMaxLength.class.getResourceAsStream("input.xml")));
// not: saxParser.parse(TestFixMaxLength.class.getResourceAsStream("input.xml"), ???);
System.out.println();
System.out.println();
System.out.println(customContentHandler.m_outputBuilder.toString());
// validation on corrected input should pass
schema.newValidator().validate(new StreamSource(new StringReader(customContentHandler.m_outputBuilder.toString())));
}
/****************************************************************************************************************************************/
private static class CustomContentHandler extends DefaultHandler {
private StringBuilder m_outputBuilder = new StringBuilder();
private SortedMap<String, String> m_prefixMappings = new TreeMap<>();
private int m_lastValueLength = 0;
private Matcher m_matcher = Pattern.compile(
"cvc-maxLength-valid: Value '(.+?)' with length = '(.+?)' is not facet-valid with respect to maxLength '(.+?)' for type '(.+?)'.",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL).matcher("");
#Override
public void error(SAXParseException e) throws SAXException {
if (e.getMessage().startsWith("cvc-maxLength-valid")) {
System.out.println("error: " + e);
m_matcher.reset(e.getMessage());
if (m_matcher.matches()) {
int maxLength = Integer.parseInt(m_matcher.group(3));
m_outputBuilder.setLength(m_outputBuilder.length() - m_lastValueLength + maxLength);
} else {
System.out.println("unexpected message format");
}
}
}
#Override
public void startDocument() throws SAXException {
System.out.println("startDocument");
}
#Override
public void endDocument() throws SAXException {
System.out.println("endDocument");
}
#Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
System.out.println("startPrefixMapping: prefix: " + prefix + ", uri: " + uri);
m_prefixMappings.put(prefix, uri);
}
#Override
public void endPrefixMapping(String prefix) throws SAXException {
System.out.println("endPrefixMapping: prefix: " + prefix);
}
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
System.out.println("startElement: uri: " + uri + ", localName: " + localName + ", qName: " + qName
+ ", attributes: " + attributes.getLength());
m_outputBuilder.append('<');
m_outputBuilder.append(qName);
for (int i = 0; i < attributes.getLength(); i++) {
m_outputBuilder.append(' ');
m_outputBuilder.append(attributes.getQName(i));
m_outputBuilder.append('=');
m_outputBuilder.append('\"');
m_outputBuilder.append(attributes.getValue(i));
m_outputBuilder.append('\"');
}
if (!m_prefixMappings.isEmpty()) {
for (Entry<String, String> mapping : m_prefixMappings.entrySet()) {
m_outputBuilder.append(" xmlns:");
m_outputBuilder.append(mapping.getKey());
m_outputBuilder.append('=');
m_outputBuilder.append('\"');
m_outputBuilder.append(mapping.getValue());
m_outputBuilder.append('\"');
}
m_prefixMappings.clear();
}
m_outputBuilder.append('>');
}
#Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("endElement: uri: " + uri + ", localName: " + localName + ", qName: " + qName);
m_outputBuilder.append('<');
m_outputBuilder.append('/');
m_outputBuilder.append(qName);
m_outputBuilder.append('>');
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println(
"characters: '" + new String(ch, start, length) + "', start: " + start + ", length: " + length);
m_outputBuilder.append(ch, start, length);
m_lastValueLength = length;
}
#Override
public void skippedEntity(String name) throws SAXException {
System.out.println("skippedEntity: name: " + name);
}
#Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
System.out.println("ignorableWhitespace: '" + new String(ch, start, length) + "', start: " + start
+ ", length: " + length);
m_outputBuilder.append(ch, start, length);
}
#Override
public void processingInstruction(String target, String data) throws SAXException {
System.out.println("processingInstruction: target: " + target + ", data: " + data);
}
#Override
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
System.out.println("resolveEntity");
return null;
}
}
}

SAX startElement is never called

I'm trying to use SAX to parse an XML but it happens that the Handler's startElement() is never called. I do not have any clues why it doesnt work.
This is my code
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.InputStream;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class ChangePasswordXMLParser {
public static void parseXML(InputStream xml) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
ChangePasswordHandler handler = new ChangePasswordHandler();
saxParser.parse(xml, handler);
} catch (Exception e) {
e.printStackTrace();
}
}
private static class ChangePasswordHandler extends DefaultHandler {
boolean bfReturn;
public ChangePasswordHandler() {
}
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("return")) {
bfReturn = true;
}
}
#Override
public void characters(char ch[], int start, int length) throws SAXException {
if (bfReturn) {
AuthenticateUserResult user = SessionManager.getInstance().getUser();
String value = new String(ch, start, length);
EventBus.getDefault().post(new AlterarSenhaEvent(value));
bfReturn = false;
}
}
}
}
and this is and XML Input example:
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body SOAP-ENC:encodingStyle="http://schemas.xmlsoap.org/soap/envelope/">
<NS1:ChangePasswordResponse xmlns:NS1="urn:exemple">
<return xsi:type="xsd:string">03351-0</return>
</NS1:ChangePasswordResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I did see in other topic here in stackoverflow that may be the imports, but my imports seems fine to me.
Any ideas? Thanks!
You set AlterarSenhaHandler instead of PasswordHandler.
So PasswordHandler is never called.
#Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equalsIgnoreCase("return")) {
System.out.println("inside return");
}
}
proofs that your code is valid

Parsing XML with XmlUtils

I am using XmlUtils to parse and extract the values of the id attribute in a List but it returns empty.
Where am I going wrong ? Please suggest
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<address-book xmlns="qwerty" xmlns:ab2="asdfgh">
<contact time-stamp="2014-02-26T16:35:20.678+02:00" id="12345">
<ns2:person-details index="9AmmUzHXBPsK:96">
<ns2:name index="1">
<ns2:name-entry index="1">
<ns2:display-name>DISP0dNXoq</ns2:display-name>
<ns2:given display-order="1">GIVENw17JCb</ns2:given>
<ns2:family display-order="1">FAMILYcl7h2y</ns2:family>
</ns2:name-entry>
</ns2:name>
<ns2:comm-addr xml:lang="en">
<ns2:uri-entry addr-uri-type="trn" index="1:1111">
<ns2:addr-uri>cnaFC#hOog6.com</ns2:addr-uri>
<ns2:label xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</ns2:uri-entry>
<ns2:tel tel-type="Home" index="2:22222">
<ns2:tel-nb>
<ns2:tel-str>97235852622</ns2:tel-str>
</ns2:tel-nb>
</ns2:tel>
<ns2:tel tel-type="Work" index="3:33333">
<ns2:tel-nb>
<ns2:tel-str>97230557837</ns2:tel-str>
</ns2:tel-nb>
</ns2:tel>
<ns2:tel tel-type="Mobile" index="3:33333">
<ns2:tel-nb>
<ns2:tel-str>972542993697</ns2:tel-str>
</ns2:tel-nb>
</ns2:tel>
</ns2:comm-addr>
</ns2:person-details>
<contact-status>
<contact-source>contact-source-sim-1393425320678</contact-source>
</contact-status>
</contact>
<contact time-stamp="2014-02-26T16:37:19.370+02:00" id="12346">
<contact time-stamp="2014-02-26T16:38:53.345+02:00" id="12347">
<contact time-stamp="2014-02-26T16:37:30.828+02:00" id="12348">
Code:
Document document = XmlUtils.createDocument(responseString);
List<Element> list = document.getRootElement().getChildren("address-book");
for( Element ele : list){
System.out.println(ele.getChild("contact").getAttribute("id").getValue());
}
Class XmlUtils-
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.xml.sax.InputSource;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.io.FileWriter;
public class XmlUtils
{
private static final Logger logger = Logger.getLogger(XmlUtils.class);
public static String getFormatedXMLString(String doc) throws JDOMException, IOException
{
return ( makeDomToFormatedString( createDocument(doc) ) ) ;
}
public static String makeDomToFormatedString(Document doc)
{
return makeDomToFormatedString(doc.getRootElement());
}
public static String makeDomToFormatedString(Element elem)
{
XMLOutputter output = new XMLOutputter();
Format format = Format.getPrettyFormat();
format.setExpandEmptyElements( true );
format.setTextMode( Format.TextMode.TRIM_FULL_WHITE );
output.setFormat( format );
return output.outputString(elem);
}
public static Document createDocument(String xml) throws JDOMException, IOException
{
InputSource in = new InputSource(new StringReader(xml));
SAXBuilder saxB = new SAXBuilder();
return ((saxB.build(in)));
}
public static Element createElement(File xmlFile) throws JDOMException, IOException
{
SAXBuilder saxB = new SAXBuilder();
Document document = saxB.build(xmlFile);
return document.getRootElement();
}
public static void writeXmlFile(Document doc,String path){
try {
XMLOutputter xmlOutputer = new XMLOutputter();
xmlOutputer.setFormat( Format.getPrettyFormat() );
xmlOutputer.output( doc , new FileWriter( path ) );
} catch (IOException e) {
logger.error("cant write xml file",e);
}
}
}
Here we go
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Namespace;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.xml.sax.InputSource;
public class XmlUtils
{
public static void main(String[] args) throws JDOMException, IOException {
String test="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><address-book xmlns=\"qwerty\" xmlns:ab2=\"asdfgh\"><contact time-stamp=\"2014-02-26T16:35:20.678+02:00\" id=\"12345\"></contact><contact time-stamp=\"2014-02-26T16:37:19.370+02:00\" id=\"12346\"></contact><contact time-stamp=\"2014-02-26T16:38:53.345+02:00\" id=\"12347\"></contact><contact time-stamp=\"2014-02-26T16:37:30.828+02:00\" id=\"12348\"></contact></address-book>";
Document document = XmlUtils.createDocument(test);
Element rootNode=document.getRootElement();
Namespace namespace=Namespace.getNamespace("qwerty");
rootNode.setNamespace(namespace);
List list = rootNode.getChildren("contact",namespace);
for (int i = 0; i < list.size(); i++) {
Element node = (Element) list.get(i);
System.out.println("id values using Style 1 : " + node.getAttribute("id").getValue());
}
List<Element> list2 = document.getRootElement().getChildren("contact",namespace);
for( Element ele : list2){
System.out.println(ele.getAttribute("id").getValue());
}
}
public static String getFormatedXMLString(String doc) throws JDOMException, IOException
{
return ( makeDomToFormatedString( createDocument(doc) ) ) ;
}
public static String makeDomToFormatedString(Document doc)
{
return makeDomToFormatedString(doc.getRootElement());
}
public static String makeDomToFormatedString(Element elem)
{
XMLOutputter output = new XMLOutputter();
Format format = Format.getPrettyFormat();
format.setExpandEmptyElements( true );
format.setTextMode( Format.TextMode.TRIM_FULL_WHITE );
output.setFormat( format );
return output.outputString(elem);
}
public static Document createDocument(String xml) throws JDOMException, IOException
{
InputSource in = new InputSource(new StringReader(xml));
SAXBuilder saxB = new SAXBuilder();
return ((saxB.build(in)));
}
public static Element createElement(File xmlFile) throws JDOMException, IOException
{
SAXBuilder saxB = new SAXBuilder();
Document document = saxB.build(xmlFile);
return document.getRootElement();
}
public static void writeXmlFile(Document doc,String path){
try {
XMLOutputter xmlOutputer = new XMLOutputter();
xmlOutputer.setFormat( Format.getPrettyFormat() );
xmlOutputer.output( doc , new FileWriter( path ) );
} catch (IOException e) {
e.printStackTrace();
}
}
}
output will be
id values using Style 1 : 12345
id values using Style 1 : 12346
id values using Style 1 : 12347
id values using Style 1 : 12348
12345
12346
12347
12348
let me know if u face any issues :)

Marshaling exception when using jaxb

I have java code and i'm trying to parse it and store it as XML file on my PC using JAXB but i have a marshaling exception:
Exception in thread "main" javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an #XmlRootElement annotation]
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:311)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:236)
at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:103)
at xml.ConfList.addToList(ConfList.java:29)
at xml.Tester.work(Tester.java:34)
at xml.Tester.main(Tester.java:16)
Caused by: com.sun.istack.internal.SAXException2: unable to marshal type "java.lang.String" as an element because it is missing an #XmlRootElement annotation
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:237)
at com.sun.xml.internal.bind.v2.runtime.LeafBeanInfoImpl.serializeRoot(LeafBeanInfoImpl.java:126)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:483)
at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:308)
... 5 more
Java Result: 1
BUILD SUCCESSFUL (total time: 9 seconds)
The JAXB code i'm using :
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class ConfList {
private static final String fileName = "Source.xml";
List<String> xmlConfList;
private Object object;
public ConfList(Object object){
this.object = object;
}
public void addToList() throws IOException, JAXBException {
File file = new File(fileName);
JAXBContext jaxbContext = JAXBContext.newInstance(XmlConf.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
jaxbMarshaller.marshal(object, file); // i got the exception here
jaxbMarshaller.marshal(object, System.out);
}
}
The main class i use:
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;
import org.xml.sax.SAXException;
public class Tester{
public static void main (String [] args) throws XPathExpressionException, IOException, ParserConfigurationException, SAXException, TransformerException, JAXBException{
work();
}
public static void work () throws IOException, ParserConfigurationException, SAXException, XPathExpressionException, TransformerException, JAXBException{
String surl = "http://api.worldweatheronline.com/free/v1/weather.ashx?q=Cairo&format=xml&num_of_days=1&key=wd63kxr294rcgvbynhaf2z4r";
XmlSource xml = new XmlSource(surl);
xml.validate();
xml.load();
ArrayList<String> paths = xml.getAllPaths();
for(String path : paths){
System.out.println(path);
}
ConfList v = new ConfList(xml.getXml());
v.addToList();
}
}
The XmlConf Class :
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name = "XmlSource")
public class XmlConf {
private URL url;
private List<String> path = new ArrayList<String>();
private String urlp;
private Map<String, String> parameters;
private String host;
public URL getUrl() {
return url;
}
#XmlAttribute(name = "URL")
public void setUrl(URL url) {
this.url = url;
}
#XmlElement
public List<String> getPath() {
return path;
}
public void setPath(String path) {
this.path.add(path);
}
#XmlElement
public void setUrlPath(String urlp){
this.urlp = urlp;
}
public String getUrlPath(){
return urlp;
}
public void setParameters(Map<String, String> parameters){
this.parameters = parameters;
}
public Map<String, String> getParameters(){
return parameters;
}
public void setHostName(String host){
this.host = host;
}
public String getHostName(){
return host;
}
}
Note that all (XmlSource class) methods are run correctly.
Below is some sample code that unmarshals some XML into an instance of XmlConf and then marshals it back to XML.
Demo
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(XmlConf.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum16762200/input.xml");
XmlConf xmlConf = (XmlConf) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(xmlConf, System.out);
}
}
input.xml/Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<XmlSource URL="http://www.example.com">
<parameters>
<entry>
<key>A</key>
<value>a</value>
</entry>
<entry>
<key>B</key>
<value>b</value>
</entry>
</parameters>
<path>foo</path>
<urlPath>bar</urlPath>
</XmlSource>

Parsing XML into a Hashmap Java

I have some information stored in XML, and I need to parse XML and store some of the values in Hashmap.
Here is the XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<section ID="1">
<Room>Room1</Room>
<Capactiy>25</Capactiy>
<Approval_Mode>personally</Approval_Mode>
<Building>Building1</Building>
<Address>Streer, 1. Stock, links</Address>
<Room_Number>ZA0115</Room_Number>
<CoordLt>16.412094</CoordLt>
<CoordLn>48.19719</CoordLn>
</section>
<section ID="2">
<Room>Room2</Room>
<Capactiy>120</Capactiy>
<Institute>E401</Institute>
<Approval_Mode>personally</Approval_Mode>
<Building>Building2</Building>
<Address>Street 2, Building2, Stiege 7, 1.Stock</Address>
<Room_Number>AH0105</Room_Number>
<CoordLt>16.369865</CoordLt>
<CoordLn>48.199006</CoordLn>
</section>
----
I want that key be:Room1 and values: 16.412094,48.19719 (example for Section ID=1)
That is example for first section.I have more than 100 section so I would like to store key and values for every section like I explained for the first example.
Output would be:
Room1: 16.412094,48.19719;
Room2: 16.369865,48.199006;
Room3: 16,48;
.
.
.
Room100: 16,49;
Can anyone help me?
Here is my code:
import java.io.File;
import java.sql.ResultSet;
import java.util.HashMap;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
public class XML extends DefaultHandler
{
static HashMap<StringBuffer, String> hashMap;
String elementName;
StringBuffer elementValue;
private HashMap<String, String> newMap;
public static void main(String[] args)
{
DefaultHandler handler = new XML();
SAXParserFactory factory = SAXParserFactory.newInstance();
try
{
hashMap = new HashMap<StringBuffer, String>();
//out = new OutputStreamWriter(System.out, "UTF8");
SAXParser saxParser = factory.newSAXParser();
saxParser.parse(new File("xml1.xml"), handler);
System.out.println(hashMap);
}
catch(Throwable t)
{
t.printStackTrace();
}
System.exit(0);
}
public void startElement(String namespaceURI, String sName, String qName, Attributes attrs)
throws SAXException
{
String eName = sName;
if("".equals(eName)) eName = qName;
elementName = eName;
if(attrs != null)
{
for(int i = 0; i < attrs.getLength(); i++)
{
String aName = attrs.getLocalName(i);
if("".equals(aName)) aName = attrs.getQName(i);
}
}
}
public void endElement(String namespaceURI, String sName, String qName)
throws SAXException
{
String eName = sName;
if("".equals(eName)) eName = qName;
if(eName.equals(elementName))
hashMap.put(elementValue,""+ elementName );
elementValue = null;
}
public void characters(char[] ch, int start, int length)
throws SAXException
{
String str = new String(ch, start, length);
if(elementValue == null)
elementValue = new StringBuffer(str);
else
elementValue.append(str);
}
}
With this code I don't get desired output.
output is:
Room=Room1, Capacity=25......
Assume your xml file is "c:/test.xml"
Then use the following code to read and put into a hash map in in the following format as you said
key=Roomnumber value=CoordLt,CoordLn
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.naming.spi.DirStateFactory.Result;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class xml {
public static void main(String[] args)
{
HashMap<String,String>hMap=new HashMap<String, String>();
File file=new File("c:/test.xml");
if(file.exists())
{
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
try
{
DocumentBuilder builder = factory.newDocumentBuilder();
Document document=builder.parse(file);
Element documentElement=document.getDocumentElement();
NodeList sList=documentElement.getElementsByTagName("section");
if (sList != null && sList.getLength() > 0)
{
for (int i = 0; i < sList.getLength(); i++)
{
Node node = sList.item(i);
if(node.getNodeType()==Node.ELEMENT_NODE)
{
Element e = (Element) node;
NodeList nodeList = e.getElementsByTagName("Room");
String roomName= nodeList.item(0).getChildNodes().item(0)
.getNodeValue();
nodeList = e.getElementsByTagName("CoordLt");
String coordValues= nodeList.item(0).getChildNodes().item(0)
.getNodeValue();
nodeList = e.getElementsByTagName("CoordLn");
coordValues=coordValues+","+ nodeList.item(0).getChildNodes().item(0)
.getNodeValue();
hMap.put(roomName, coordValues);
}
}
}
} catch(Exception e){
System.out.println("exception occured");
}
}else
{
System.out.println("File not exists");
}
}
}
If you transform the XML using this xslt (which can be done in Java) you get your desired output, If someone sle knows howto load in a hashmap you'll be fine.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="no" omit-xml-declaration ="yes" />
<xsl:template match="/sections">
<xsl:apply-templates select="section"/>
</xsl:template>
<xsl:template match="section" xml:space="default">
<xsl:apply-templates select="Room"/>
<xsl:text>:</xsl:text>
<xsl:apply-templates select="CoordLt" />
<xsl:text>,</xsl:text>
<xsl:apply-templates select="CoordLn"/>
<xsl:text>;</xsl:text>
</xsl:template>
</xsl:stylesheet>

Categories

Resources