Какие методы можно использовать для возврата действительных и недействительных данных XML из файла в Java? - PullRequest
0 голосов
/ 25 августа 2018

У меня есть следующие данные, которые должны быть XML:

<?xml version="1.0" encoding="UTF-8"?>
<Product>
    <id>1</id>
    <description>A new product</description>
    <price>123.45</price>
</Product>

<Product>
    <id>1</id>
    <description>A new product</description>
    <price>123.45</price>
</Product>

<ProductTTTTT>
    <id>1</id>
    <description>A new product</description>
    <price>123.45</price>
</Product>

<Product>
    <id>1</id>
    <description>A new product</description>
    <price>123.45</price>
</ProductAAAAAA>

Итак, в основном у меня есть несколько корневых элементов (product) ...

Дело в том, чтоЯ пытаюсь преобразовать эти данные в 2 XML-документа, 1 для допустимых узлов и других для недействительных узлов.

Допустимый узел:

<Product>
   ...
</Product>

Недопустимые узлы: <ProductTTTTT>...</Product> и <Product>...</ProductAAAAAA>

Тогда я думаю, как мне этого добиться, используя JAVA (не web).

  • Если я не ошибаюсь, проверка его с помощью XSD сделает недействительным весь файл, поэтомуне вариант.
  • Использование парсера JAXB по умолчанию (unmarshaller) приведет к приведенному выше пункту, поскольку внутренне он создает XSD моей сущности.
  • Использование XPath просто (из того, что я знаю) просто вернетвесь файл, я не нашел способ получить что-то вроде GET! VALID (это просто объяснить ...)
  • Использование XQuery (может быть?) .. кстати, как использовать XQuery сJAXB?
  • XSL (T) приведет к тому же в XPath, так как он использует XPath для выбора содержимого.

Итак ... какой метод я могу использовать для достижения цели?(И, если возможно, укажите ссылки или код, пожалуйста)

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Если файл содержит строки с начальным и конечным тегами, имя которых начинается с «Product», вы можете:

  • использовать сканер файлов, чтобы разбить этот документ на отдельные части, когда строка начинается с <Product или </Product
  • попытка проанализировать извлеченный текст как XML с использованием XML API.
    • Если это удастся, добавьте этот объект в список «хороших» правильно сформированных документов XML
      • , а затем выполните любые дополнительные проверки или проверки достоверности схемы
    • Если выдается ошибка разбора, перехватите ее и добавьте этот фрагмент текста в список «плохих» элементов, которые необходимо очистить или обработать другим способом

Пример для начала:

package com.stackoverflow.questions.52012383;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

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

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class FileSplitter {

    public static void parseFile(File file, String elementName) 
      throws ParserConfigurationException, IOException {

        List<Document> good = new ArrayList<>();
        List<String> bad = new ArrayList<>();

        String start-tag = "<" + elementName;
        String end-tag = "</" + elementName;
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        StringBuffer buffer = new StringBuffer();
        String line;
        boolean append = false;

        try (Scanner scanner = new Scanner(file)) {
            while (scanner.hasNextLine()) {
                line = scanner.nextLine();

                if (line.startsWith(startTag)) {
                    append = true; //start accumulating content
                } else if (line.startsWith(endTag)) {
                    append = false;
                    buffer.append(line); 
                    //instead of the line above, you could hard-code the ending tag to compensate for bad data:
                    // buffer.append(endTag + ">");

                    try { // to parse as XML
                        builder = factory.newDocumentBuilder();
                        Document document = builder.parse(new InputSource(new StringReader(buffer.toString())));
                        good.add(document); // parsed successfully, add it to the good list

                        buffer.setLength(0); //reset the buffer to start a new XML doc

                    } catch (SAXException ex) {
                        bad.add(buffer.toString()); // something is wrong, not well-formed XML
                    }
                }

                if (append) { // accumulate content
                    buffer.append(line);
                }
            }
            System.out.println("Good items: " + good.size() + " Bad items: " + bad.size());
            //do stuff with the good/bad results...
        }
    }

    public static void main(String args[]) 
      throws ParserConfigurationException, IOException {
        File file = new File("/tmp/test.xml");
        parseFile(file, "Product");
    }

}
0 голосов
/ 25 августа 2018

Во-первых, вы сбиваете с толку действительные и правильно сформированные. Вы говорите, что хотите найти недопустимые элементы, но ваши примеры не просто недействительны, они плохо сформированы. Это означает, что никакой синтаксический анализатор XML не будет ничего с ними делать, кроме как выдавать вам сообщение об ошибке. Вы не можете использовать JAXB или XPath, или XQuery, или XSLT, или что-то еще для обработки чего-то, что не является XML.

Вы говорите: "К сожалению, у меня нет доступа к системе, которая отправляет этот формат XML". Я не уверен, почему вы называете это форматом XML: это не так. Я также не понимаю, почему вы (и многие другие в StackOverflow) готовы тратить свое время на копание мусора, а не на то, чтобы сказать отправителю собраться вместе. Если бы вам подали салат с личинками, попытались бы вытащить его или отправили обратно на замену? Вы должны принять нулевую терпимость к плохим данным; только так отправители могут научиться улучшать качество.

...