VelNaga
VelNaga

Reputation: 3953

Store xml value as a Map using XPATH using JAVA

I am using XPATH to parse xml document,please find the xml below

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <bookEvent>
            <bookName>harry_potter</bookName>
            <bookEntity>comic</bookEntity>
            <bookEntityId>10987645</bookEntityId>
            <bookParameter>
                <name>Name1</name>
                <value>value1</value>
            </bookParameter>
            <bookParameter>
                <name>Name2</name>
                <value>value2</value>
            </bookParameter>
            <bookParameter>
                <name>Name3</name>
                <value>value3</value>
            </bookParameter>
            <bookParameter>
                <name>Name4</name>
                <value>value4</value>
            </bookParameter>
            <bookParameter>
                <name>Name5</name>
                <value>value5</value>
            </bookParameter>
        </bookEvent>
    </soap:Body>
</soap:Envelope>

Here I would like to convert BookParameters to Map like below

{"Name1":"value1","Name2":"value2" etc}

I have tried the below code and i can get a Map but not in the expected format,

      try{
        Map<String,String> eventParameters = new HashMap<>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse("book.xml");
        XPathFactory xPathfactory = XPathFactory.newInstance();
        XPath xpath = xPathfactory.newXPath();
        NodeList nodeList = (NodeList)xpath.compile("//bookEvent//eventParameter").evaluate(doc, XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if(node.hasChildNodes()) {
                NodeList childNodes = node.getChildNodes();
                for (int j = 0; j < childNodes.getLength(); j++) {
                    Node childNode = childNodes.item(j);
                    if (childNode.getNodeType() == Node.ELEMENT_NODE) {
                        System.out.println(childNode.getNodeName()+"::"+childNode.getNodeValue()+"::"+childNode.getTextContent());
                        eventParameters.put(childNode.getTextContent(),childNode.getTextContent());
                    }
                }
            }
        }
        System.out.println("print map::"+eventParameters);
    } catch (Exception e) {
        e.printStackTrace();
    }

The output looks like this

print map::{Name3=Name3, Name4=Name4, value5=value5, Name5=Name5, value2=value2, value1=value1, value4=value4, value3=value3, Name1=Name1, Name2=Name2}

Please somebody guide me to create a below map from the xml,Any help would be appreciable.

{"Name1":"value1","Name2":"value2" etc}

Upvotes: 0

Views: 1225

Answers (2)

dangi13
dangi13

Reputation: 1275

Use Below code :

import java.io.File;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ReadXMLFile {

    public static Map<String,String> hMap = new LinkedHashMap<>();
    public static void main(String argv[]) {

        try {

            File fXmlFile = new File("C:\\Users\\jaikant\\Desktop\\QUESTION.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);
            doc.getDocumentElement().normalize();

            NodeList nodeList = doc.getElementsByTagName("bookParameter");

            for (int parameter = 0; parameter < nodeList.getLength(); parameter++) {
                Node node = nodeList.item(parameter);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element eElement = (Element) node;
                    String name = eElement.getElementsByTagName("name").item(0).getTextContent();
                    String value = eElement.getElementsByTagName("value").item(0).getTextContent();
                    hMap.put(name, value);

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

        hMap.forEach((h,k) -> {
            System.out.println(h + ":" + k);
        });
    }

}

It will print exactly what you are looking for.

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163322

You can do it as a one-liner in XPath 3.1:

map:merge(//bookParameter!map{string(name): string(value)}) 
   => serialize(map{'method':'json'})

You can run XPath 3.1 from Java by installing Saxon-HE 9.8 (open source)

Upvotes: 2

Related Questions