Как преобразовать XML в хэш-карту, игнорируя родительско-дочерние отношения - PullRequest
0 голосов
/ 24 мая 2019

У меня есть этот XML:

<XmlParent>
    <name>koraytugay</name>
    <bar>
        <baz>
            <to>Tove</to>
            <qux>00000001</qux>
        </baz>
    </bar>
    <note>
        <from>Jani</from>
        <heading>Reminder</heading>
        <body>Don't forget me this weekend!</body>
    </note>
</XmlParent>

Я хочу найти «to» и «from» и извлечь эти данные. Формат XML не всегда будет одинаковым, но «from» и «to»"всегда будет присутствовать (фактические узлы для поиска будут настроены в файле свойств)

Я собираюсь сделать это путем преобразования в файл json, поэтому я бы хотел, чтобы он выглядел следующим образом

{
    to:Tove
    qux:00000001
    from:Jani
    heading:Reminder
    body:Don't forget me this weekend!
}

В настоящее время я получаю это так

    XmlParent:
    {
        name:koraytugay
        bar:
        {
            baz: 
            {
                to:Tove
                qux:00000001
            }
        }
        note:
        {
            from:Jani
            heading:Reminder
            body:Don't forget me this weekend!
        }
    }
}

Я пробовал несколько различных методов.У меня есть XSD, который выглядит следующим образом (удалил фактические данные из тега схемы, но это работает нормально)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
    xmlns=""
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:tns=""
    targetNamespace=""
    elementFormDefault="unqualified" attributeFormDefault="unqualified">

    <xs:annotation>
        <xs:documentation xml:lang="en">
            Initial Draft
        </xs:documentation>
    </xs:annotation>
    <xs:element name="XMLExample">
        <xs:complexType>
            <xs:sequence>
                 <xs:any minOccurs="0" maxOccurs="unbounded"/> 
            </xs:sequence>
        </xs:complexType>
    </xs:element>

</xs:schema>

Это то, что я сейчас делаю

private static final Log LOGGER = LogFactory.getLog(XmlConverter.class);

    public Map<String, Object> xmlStringToHashMap(String xml) {
        JSON json = xmlStringToJSON(xml);

        return jsonToMap(json.toString(2));

    }

    public Map<String, Object> jsonToMap(String jsonString) {
        ObjectMapper mapper = new ObjectMapper();

        try {

            Map<String, Object> jsonInMap = mapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {
            });

            LOGGER.info("JSON Map created: " + jsonInMap);

            return jsonInMap;
        } catch (IOException e) {
            LOGGER.error(e.getMessage());
        }
        return null;
    }

    public JSON xmlStringToJSON(String xml) {
        XMLSerializer xmlSerializer = new XMLSerializer();
        return xmlSerializer.read(xml);

    }

Любая идея, какдобавить элементы и их данные в один файл JSON или HashMap, игнорируя родительские теги?

Ответы [ 2 ]

1 голос
/ 24 мая 2019

Мне удалось решить это с помощью выражения XPath //to/text()

Вот мое решение:

private String[] elements;

    public Map<String, Object> xPathParser(String xmlString) {
        try {
            Document xmlDoc = xmlStringToDocument(xmlString);

            XPath xpath = XPathFactory.newInstance().newXPath();
            String expression;
            Map<String, Object> elements = new HashMap<>();
            for (String element : elements) {
                expression = MessageFormat.format("//{0}/text()", element);

                Object xpathValue = xpath.compile(expression).evaluate(xmlDoc, XPathConstants.STRING);

                elements.put(element, xpathValue);
            }

            return elements;

        } catch (SAXException | IOException | ParserConfigurationException | XPathExpressionException e) {
            LOGGER.error(e.toString());
            return null;
        }
    }
0 голосов
/ 24 мая 2019

Возможно, вы захотите взглянуть на jsoup , библиотеку Java для анализа HTML или XML.Я часто использую его, когда хочу выполнить работу без необходимости писать колоссальный объем кода.Для вашего приведенного примера:

import java.util.HashMap;
import java.util.Map;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;

public class NewClass3 {
    public static void main(String[] args) {
        String xml = "<XmlParent>\n" +
                        "    <name>koraytugay</name>\n" +
                        "    <bar>\n" +
                        "        <baz>\n" +
                        "            <to>Tove</to>\n" +
                        "            <qux>00000001</qux>\n" +
                        "        </baz>\n" +
                        "    </bar>\n" +
                        "    <note>\n" +
                        "        <from>Jani</from>\n" +
                        "        <heading>Reminder</heading>\n" +
                        "        <body>Don't forget me this weekend!</body>\n" +
                        "    </note>\n" +
                        "</XmlParent>";

        Document doc    = Jsoup.parse(xml, "", Parser.xmlParser());
        Element to      = doc.selectFirst("to");
        Element from    = doc.selectFirst("from");
        Element qux     = doc.selectFirst("qux");
        Element heading = doc.selectFirst("heading");
        Element body    = doc.selectFirst("body");

        //print put in map or whatever...
        System.out.println("to: "   + to.text());
        System.out.println("from: " + qux.text());

        Map<String,String> map = new HashMap<>();
        map.put("to", to.text());
    }    
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...