-1

How can I convert all attributes of XML to a Map of Strings? I need output as key and value in a Map. i.e Map<String, String>

    <persons xmlns="http://www.sample.com/restapi" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <delivery></delivery>
    <Order>1</Order>
    <person1>
        <personorder>
            <email>abc@abc.com</email>
            <name>Smith </name>
            <data>
                <approvedata>
                    <approve>
                        <Label>Consent</Label>
                        <underline>false</underline>
                    </approve>
                </approvedata>
            </data>
        </personorder>
    </person1>
    </persons>



    output :
...............................
        Order,1
        email,abc@abc.com
        Label,Consent
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
gnr14
  • 21
  • 1
  • 1
  • 10
  • Well, it may not be possible because imagine there are 2 person objects. Now, we need to store both the email of the person's under one name. So one of the person's email will always get overridden. how would you like to handle such scenario? I mean the expected output? – Kishore Bandi Nov 22 '16 at 16:48
  • Have you tried *anything*? There are numerous resources covering parsing XML in java. All you have to do is search for them. – tnw Nov 22 '16 at 16:50
  • Possible duplicate ? http://stackoverflow.com/questions/1537207/how-to-convert-xml-to-java-util-map-and-vice-versa – Derek_M Nov 22 '16 at 16:52

1 Answers1

0

I was able to achieve the solution using XPath. The xpath query searches for leaf elements that have any text. Then a simple loop converts the xpath result NodeList to Map.

Here is the solution wrapped in one method:

public static Map<String, String> getElementsWithText(Document xmlDoc) throws XPathException
{
    Map<String, String> elementsWithText = new HashMap<>();

    final String leafElementsWithTextXPathQuery = "//*[not(child::*) and text()]";
    XPath xPath =  XPathFactory.newInstance().newXPath();
    NodeList list = (NodeList)xPath.compile(leafElementsWithTextXPathQuery)
        .evaluate(xmlDoc, XPathConstants.NODESET);
    for (int i = 0; i < list.getLength() ; i++) {
        Node node = list.item(i);
        elementsWithText.put(node.getNodeName(), node.getTextContent());
    }
    return elementsWithText;
}

Here is a test main that loads the xml from question:

public static void main(String[] args)
{
    try {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document xmlDoc = builder.parse(new InputSource(new FileReader("C://Temp/xx.xml")));
        System.out.println(getElementsWithText(xmlDoc));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Output from println:

{Order=1, underline=false, name=Smith , Label=Consent, email=abc@abc.com}
Sharon Ben Asher
  • 13,849
  • 5
  • 33
  • 47