Запись с Java в XML-документ — просто

Я знаю, что в stackoverflow есть куча вопросов по записи с Java на XML, но все это слишком сложно. Я чувствую, что у меня есть очень простая проблема, которую я просто не могу понять.

Итак, у меня есть программа, которая принимает кучу пользовательского ввода, и в настоящее время я создаю и добавляю текстовый документ с результатами. Я просто опубликую свой код писателя здесь:

 PrintWriter out = null;
         try {
             out = new PrintWriter(new BufferedWriter(new FileWriter("C:/Documents and Settings/blank/My Documents/test/test.txt", true)));
             out.println("");
             out.println("<event title=\""+titleFieldUI+"\"");
             out.println("  start=\""+monthLongUI+" "+dayLongUI+" "+yearLongUI+" 00:00:00 EST"+"\"");            
             out.println("  isDuration=\"true\"");
             out.println("  color=\""+sValue+"\"");
             out.println("  end=\""+monthLong1UI+" "+dayLong1UI+" "+yearLong1UI+" 00:00:00 EST"+"\"");
             out.println("  "+descriptionUI);
             out.println("");
             out.println("</event>");
             out.println("  <!-- Above event added by: " +System.getProperty("user.name")+" " +
                        "on: "+month+"/"+day+"/"+year+" -->");       
         }catch (IOException e) {
             System.err.println(e);
         }finally{
             if(out != null){
                 out.close();
             }
         } 

Итак, в конце концов, я хочу, чтобы он записывался в уже существующий файл XML (что я могу сделать, просто изменив, куда идет мой писатель). Проблема в том, что этот файл XML имеет ОДИН корневой тег, известный как <data>. Мне нужно, чтобы результаты моей программы находились в нижней части XML-файла, но ДО </data>. Это единственное требование. Все, что я нахожу, кажется слишком сложным, и я не могу понять это.

Любая помощь очень ценится!


person user2221125    schedule 04.04.2013    source источник


Ответы (3)


Вы должны использовать достойный XML API. Например, вот пример использования JDOM:

import java.io.*;

import org.jdom2.*;
import org.jdom2.input.*;
import org.jdom2.output.*;

public class Test {
    public static void main(String args[]) throws IOException, JDOMException {
        File input = new File("input.xml"); 
        Document document = new SAXBuilder().build(input);
        Element element = new Element("event");
        element.setAttribute("title", "foo");
        // etc...
        document.getRootElement().addContent(element);

        // Java 7 try-with-resources statement; use a try/finally
        // block to close the output stream if you're not using Java 7
        try(OutputStream out = new FileOutputStream("output.xml")) {
            new XMLOutputter().output(document, out);
        }
    }
}

Это на самом деле не так уж и сложно... и будет намного, намного надежнее, чем писать вручную. (Например, это будет правильно, если заголовок вашего события содержит «&», тогда как ваш код создал бы недопустимый XML.)

person Jon Skeet    schedule 04.04.2013
comment
Как добавить комментарий в XML-документ с помощью JDOM? - person MariuszS; 05.04.2013
comment
@MariuszS: я не знал, поэтому посмотрел документацию. У меня это не заняло много времени, и я уверен, что это не займет много времени и у вас :) - person Jon Skeet; 05.04.2013
comment
Привет, Джон, на самом деле я пишу программу для обновления файла XML для SIMILIE Timeline Creator. Создатель не использует никаких XML-тегов, кроме ‹data› и ‹event›, поэтому установка этих элементов, я думаю, мне не подойдет. - person user2221125; 08.04.2013
comment
@ user2221125: Я понятия не имею, что вы имеете в виду. Мой пример кода добавляет только тег event. Как вы думаете, что не будет работать с кодом, который я дал? - person Jon Skeet; 08.04.2013
comment
@ Джон Скит, кажется, я понятия не имею, о чем говорю, ха-ха. Я буду больше изучать JDOM, чтобы посмотреть, смогу ли я заставить его работать на меня. Спасибо! :) - person user2221125; 08.04.2013
comment
@user2221125 user2221125 Мое решение готово и работает, просто запустите его :) - person MariuszS; 28.04.2013
comment
@Mariusz@ Я уже нашел решение, но большое спасибо за помощь! - person user2221125; 10.05.2013

Если вам нравится свободный API, вы можете использовать JOOX:

File file = new File("projects.xml");

Document document = $(file).document();

Comment eventComment = document.createComment("Above event added by: "
        + System.getProperty("user.name") + "\n" +
        " on: " + month + "/" + day + "/" + year);

document = $(file)
        .xpath("//data")
        .append($("event",
                $("title", "titleFieldUI"),
                $("start", monthLongUI + " " + dayLongUI + " " + yearLongUI + " 00:00:00 EST"),
                $("isDuration", "true"),
                $("color", sValue),
                $("end", monthLong1UI + " " + dayLong1UI + " " + yearLong1UI + " 00:00:00 EST")))
        .append($(eventComment))
        .document();

Transformer transformer = TransformerFactory.newInstance().newTransformer();
Result output = new StreamResult(file);
Source input = new DOMSource(document);

transformer.transform(input, output);

или XMLBuilder.

XMLBuilder builder = XMLBuilder.parse(
        new InputSource(new FileReader("C:/Documents and Settings/blank/My Documents/test/test.txt")))
        .xpathFind("//data")
        .e("event")
        .a("title", titleFieldUI)
        .a("start", monthLongUI + " " + dayLongUI + " " + yearLongUI + " 00:00:00 EST")
        .a("isDuration", "true")
        .a("color", sValue)
        .a("end", monthLong1UI + " " + dayLong1UI + " " + yearLong1UI + " 00:00:00 EST")
        .up()
        .comment("Above event added by: " + System.getProperty("user.name") + "\n" +
                " on: " + month + "/" + day + "/" + year);

PrintWriter writer = new PrintWriter(new FileOutputStream("C:/Documents and Settings/blank/My Documents/test/test.txt"));
builder.toWriter(writer, new Properties());
person MariuszS    schedule 04.04.2013
comment
Это мне не помогает, так как я не хочу создавать файл XML. Файл XML уже существует, мне нужно добавить к нему информацию, введенную из моей программы с графическим интерфейсом. - person user2221125; 05.04.2013
comment
Ты слишком быстр :) Это не было завершено :D - person MariuszS; 05.04.2013
comment
Я не думаю, что StringReader делает то, что вы думаете. - person Jon Skeet; 05.04.2013

Вы можете использовать JOOX. Вот как вы могли бы сделать добавление:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder parser = factory.newDocumentBuilder();
Document doc = parser.parse("/pathToXML");

JOOX.$(doc).append("<newNode>data<newNode>");

По умолчанию $(doc) загружает корневой узел. Если вам нужен внутренний узел, вы можете использовать метод find(). Библиотека не очень хорошо документирована, но, поскольку исходный код открыт, вы всегда можете напрямую проверить исходники.

person Vlad Topala    schedule 04.04.2013
comment
Вы можете создать документ с помощью следующего кода: $(new File(/pathToXML)).document(); - person MariuszS; 06.04.2013