user8142520
user8142520

Reputation: 781

read xml content from http endpoint like a map in Java

How could I get value based on a key from an XML content http enpoint, so it is something like

<authority.result result="found 7 matches" startToken="xxxxxxx">
<TestEntry keyId="0right0" test="test" valueId="rightValue123" version="1"/>
<TestEntry keyId="0wrong" test="test" valueId="0wrongValue" version="1"/>
<TestEntry keyId="0wrong0" test="test" valueId="wrong" version="1"/>
</authority.result>

I would like to get the valueId when keyId=="0right0" only, I previously wrote following but could not get value for a specific key.

            URL url = new URL(endpoint);
            XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(url.openStream());
            String latest;
            while (reader.hasNext()) {
                if (reader.next() == XMLStreamConstants.START_ELEMENT) {
                    if (reader.getLocalName().equals("valueId")) {
                        latest = reader.getElementText();
                        return latest;
                    }
                }
            }

Upvotes: 1

Views: 247

Answers (2)

SomeDude
SomeDude

Reputation: 14238

You could use an xpath to get to the desired value :

string(//TestEntry[@keyId="0right0"]/@valueId)

Upvotes: 0

Michał Ziober
Michał Ziober

Reputation: 38710

You need to distinguish XML element from an attribute. To read attribute name and value you have to use getAttributeName and getAttributeValue methods respectively.

Below you find example code how to read attributes:

import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;

public class XmlStreamApp {
    public static void main(String[] args) throws IOException, XMLStreamException {
        ...
        XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(stream);
        Optional<String> value = findValueForTestEntry(reader, "0right0");
        System.out.println(value);
    }

    private static Optional<String> findValueForTestEntry(XMLStreamReader reader, String keyValue) throws XMLStreamException {
        while (reader.hasNext()) {
            if (reader.next() == XMLStreamConstants.START_ELEMENT) {
                String localName = reader.getLocalName();
                if ("TestEntry".equals(localName)) {
                    Optional<String> optionalValue = getValueForKey(reader, keyValue);
                    if (optionalValue.isPresent()) {
                        return optionalValue;
                    }
                }
            }
        }
        return Optional.empty();
    }

    private static Optional<String> getValueForKey(XMLStreamReader reader, String keyValue) {
        String value = "";
        boolean found = false;
        for (int attr = reader.getAttributeCount() - 1; attr >= 0; attr--) {
            QName attributeName = reader.getAttributeName(attr);
            if (attributeName.getLocalPart().equals("keyId")) {
                found = keyValue.equals(reader.getAttributeValue(attr));
            }
            if (attributeName.getLocalPart().equals("valueId")) {
                value = reader.getAttributeValue(attr);
            }
        }
        return found ? Optional.of(value) : Optional.empty();
    }
}

Above code prints:

Optional[rightValue123]

Upvotes: 1

Related Questions