0

Imagine an XML document like this:

<?xml version="1.0" encoding="UTF-8" ?>
<books>
  <book name="book1"></book>
  <book name="book2"></book>
</books>

I want to write the doc to a new file after filtering out some books. I'm using JOOX and have some code like this:

final FastFilter nameFilter = new FastFilter() {
    final Set<String> validNames = new HashSet<>();//contains "book1"
    @Override public boolean filter(Context context) {
        return !validNames.contains($(context).attr("name"));
    }
};      
final Document doc = $(new StringReader("entire text of xml document...")).document();
final Match m = $(doc).find("book").remove(nameFilter);

I tried something like this m.write(new File(output.xml));, but that outputs only:

<book name="book1"></book>

In other words it is missing the parent element <books> and also the initial XML declaration. Any idea how to accomplish this? Looking for a simple/elegant solution preferably using JOOX, not 20 lines of DOM code :)

Dave L.
  • 9,595
  • 7
  • 43
  • 69

1 Answers1

2

You probably figured this out already, but in case you haven't:

The Match m in your example represents the element* you wish to remove, in this case the book element with name="book1". When you call write() on a Match, it is only the element(s) of that Match which is written. Hence, when you do m.write(new File(output.xml)); you end up with

<book name="book1"></book> 

But the remove method removes the element(s) represented by the match (i.e. the book element with name "book1") from the Document you used to create/find the Match. So when you do remove(nameFilter), that element is actually removed from the Document doc.

After the element is removed from the Document, if you want the entire edited Document written to file, you call the write method of (a Match of) the Document itself:

$(doc).write(new File(output.xml)); 

*) Do note that a Match can contain several elements. You can use m.size() to check the number of elements in your Match.

reowil
  • 384
  • 3
  • 10
  • Can you be more specific about that last part? I don't want to write the entire original document of course -- but the entire document minus the element that was filtered out. – Dave L. Jun 30 '15 at 16:40
  • @david: Ah, sorry I wasn't totally clear on that. It is in fact the edited document (without the filtered out element) which is written, not the original document, because the remove method operates on the document. I edited my answer to include more info - I hope that helps. – reowil Jul 01 '15 at 18:56
  • 1
    Yeah, that basically works, but when doing the `write` method like you do it still doesn't print the declaration line ``. Is that expected? Thanks – Dave L. Jul 16 '15 at 01:22
  • 1
    @david: I'm sorry, but I haven't found a way to do that using jOOX. If you find a jOOX solution, I would love to know about it! – reowil Jul 28 '15 at 19:11