анализируемый inputtream xml формат java - PullRequest
0 голосов
/ 05 мая 2018

У меня есть InputStream , содержащий формат xml, как показано ниже: -

InputStream is = asStream("<TransactionList>\n" +
            "    <Transaction type=\"C\" amount=\"1000\"narration=\"salary\" />\n" +
            "    <Transaction type=\"X\" amount=\"400\" narration=\"rent\"/>\n" +
            "    <Transaction type=\"D\" amount=\"750\" narration=\"other\"/>\n" +
            "</TransactionList>");
 xmlTransactionProcessor.importTransactions(is);

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

Я испробовал много решений, но пока не получил никаких преимуществ.

Я читал о чтении XML-файлов, но все еще не могу справиться с InputStream, подобным этому.

Кто-нибудь может помочь? Это моя последняя попытка, но она все еще где-то терпит неудачу.

    // TODO Auto-generated method stub
    BufferedReader inputReader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();
    String inline = "";
    try {
        while ((inline = inputReader.readLine()) != null) {
          sb.append(inline);
        }
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    SAXBuilder builder = new SAXBuilder();

    try {
        org.jdom2.Document document = (org.jdom2.Document) builder.build(new ByteArrayInputStream(sb.toString().getBytes()));
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Вам не нужно самостоятельно анализировать XML с помощью SAX-анализатора. Существует несколько библиотек, которые позволяют XML Binding : сериализовать и десериализовать XML-документы в пользовательские классы POJO (или их коллекцию).

В JDK даже есть стандарт для связывания XML. Он называется JAXB . Вы можете использовать аннотации для сопоставления имен элементов XML со свойствами вашего пользовательского POJO.

Вот пример с моей личной библиотекой фаворитов: Джексон . Он в первую очередь предназначен для обработки текста в формате JSON, но имеет расширение для поддержки XML (и JAXB).

import java.util.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.dataformat.xml.*;

public class XMLTest
{
    public static void main(String[] args)
    {
        String input = 
            "<TransactionList>\n" +
            "    <Transaction type=\"C\" amount=\"1000\" narration=\"salary\" />\n" +
            "    <Transaction type=\"X\" amount=\"400\" narration=\"rent\"/>\n" +
            "    <Transaction type=\"D\" amount=\"750\" narration=\"other\"/>\n" +
            "</TransactionList>";
        try {
            XmlMapper xmlMapper = new XmlMapper();
            xmlMapper.setDefaultUseWrapper(false);
            // this is how we tell Jackson the target type of the deserialization 
            JavaType transactionListType = xmlMapper.getTypeFactory().constructCollectionType(List.class, Transaction.class);
            List<Transaction> transactionList = xmlMapper.readValue(input, transactionListType );
            System.out.println(transactionList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static class Transaction
    {
        public String type;
        public int amount;
        public String narration;

        @Override
        public String toString() {
            return String.format("{ type:%s, amount:%d, narration:%s }", type, amount, narration);   
        }

    }
}
0 голосов
/ 05 мая 2018

Как объяснила Шарон Бен Ашер, вы можете использовать аннотированное отображение данных, используя JAXB или Джексона с форматером данных XML . Это было бы проще.

Если вы хотите исправить существующий код с помощью SAXParser, вот как это делается.

Вы должны выполнить итерацию объекта документа, как показано в коде ниже.

public static void main(String[] args) {
    InputStream is = new ByteArrayInputStream(("<TransactionList>\n" +
            "    <Transaction type=\"C\" amount=\"1000\" narration=\"salary\" />\n" +
            "    <Transaction type=\"X\" amount=\"400\" narration=\"rent\"/>\n" +
            "    <Transaction type=\"D\" amount=\"750\" narration=\"other\"/>\n" +
            "</TransactionList>").getBytes(StandardCharsets.UTF_8));
    ArrayList transactions = importTransactions(is);
}

В методе importTransaction используйте getRootElement для получения корневого элемента Transactions . Затем выполните итерацию по каждому дочернему элементу Transaction , используя getChildren и цикл for-each.

public static ArrayList<Transaction> importTransactions(InputStream is){
        ArrayList<Transaction> transactions = new ArrayList<>();
        BufferedReader inputReader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String inline = "";
        try {
            while ((inline = inputReader.readLine()) != null) {
                sb.append(inline);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        SAXBuilder builder = new SAXBuilder();

        try {
            org.jdom2.Document document = builder.build(new ByteArrayInputStream(sb.toString().getBytes()));
            Element transactionsElement = document.getRootElement();

            List<Element> transactionList = transactionsElement.getChildren();

            for (Element transaction:transactionList) {
                Transaction t = new Transaction();
                t.setType(transaction.getAttribute("type").getValue());
                t.setAmount(transaction.getAttribute("amount").getValue());
                transactions.add(t);

            }

        } catch (Exception e) {
            // Log the error....
            e.printStackTrace();
        }
        return transactions;
    }
...