dorien
dorien

Reputation: 5407

Iterating over different elements and changing a particular one in JSoup

I need to change a few elements, which are nested deep within a musicxml file. I use jSoup to parse the document and perform my calculations.

Now I want to expert the jsoup doc and make a few modifications first. The problem is, within the xml file, the elements don't have a unique identifier (e.g. there are many notes and measures, notes are not numbered).

I loop through the document like this. And after certain criteria are met, I want to change the particular note. Using this iter in java uses a copy, so modifying the elements doesn't make a difference on the original doc. Could I use for i = 0; i < ?? or something? Would this go over the elements in the same order (important for checking criteria).

for (Element thismeasure : thisPart.getElementsByTag("measure")) {

                for (Element thisnote : thismeasure.children()) {

Upvotes: 1

Views: 1735

Answers (2)

dorien
dorien

Reputation: 5407

I used a more "traditional" method:

for (int z = 0; z < this.doc.select("part").size(); z++ ){
            for (int y = 0; y <  this.doc.select("part").get(z).getElementsByTag("measure").size(); y++){
...

This allows me to use the set method to change the elements in the actual doc variable.

Upvotes: 1

fonkap
fonkap

Reputation: 2509

Sorry if I didn't understand your question well:

What do you mean by "so modifying the elements doesn't make a difference on the original doc"?

Using a simple xml I can make some changes using your loop, the testing xml will be:

<measure><note/><note at='1'/></measure>

I will find the note with attribute at='1', and then I will add text to it and a node before and after it, then I will check that the original doc is changed, the code:

public static void main(String[] args) {
    String xml = "<measure><note/><note at='1'/></measure>";
    Document parse = Jsoup.parse(xml, "", Parser.xmlParser());


    for (Element thismeasure : parse.getElementsByTag("measure")) {

        for (Element thisnote : thismeasure.children()) {
            if (thisnote.attr("at").equals("1")){
                thisnote.text("newText");
                thisnote.attr("newAttr", "value");
                thisnote.before(new Element(Tag.valueOf("test1"),""));
                thisnote.after(new Element(Tag.valueOf("test2"),""));
            }
        }
    }

    System.out.println(parse);
}

Will output:

<measure>
<note />
<test1></test1>
<note at="1" newattr="value">
 newText
</note>
<test2></test2>
</measure>

As expected.

I hope it will help in any way.

Upvotes: 1

Related Questions