kyle
kyle

Reputation: 115

Reading XML with jsoup

I'm new to java, and certainly new to jsoup. In this preliminary step of my program, I'm trying to get a web based XML file into an object I can start using to output my content. (It is a huge XML file, and I want to eventually be able to add filters)

Here is some sample XML.

<spell>
    <name>Acid Splash</name>
    <level>0</level>
    <school>C</school>
    <time>1 action</time>
    <range>60 feet</range>
    <components>V, S</components>
    <duration>Instantaneous</duration>
    <classes>Sorcerer, Wizard, Fighter (Eldritch Knight), Rogue (Arcane Trickster)</classes>
    <text>You hurl a bubble of acid. Choose one creature within range, or choose two creatures within range that are within 5 feet of each other. A target must succeed on a Dexterity saving throw or take 1d6 acid damage.</text>
    <text />
    <text>This spells damage increases by 1d6 when you reach 5th Level (2d6), 11th level (3d6) and 17th level (4d6).</text>
    <roll>1d6</roll>
    <roll>2d6</roll>
    <roll>3d6</roll>
    <roll>4d6</roll>
</spell>
<spell>
    <name>Aid</name>
    <level>2</level>
    <school>A</school>
    <time>1 action</time>
    <range>30 feet</range>
    <components>V, S, M (a tiny strip of white cloth)</components>
    <duration>8 hours</duration>
    <classes>Artificer, Cleric, Paladin</classes>
    <text>Your spell bolsters your allies with toughness and resolve. Choose up to three creatures within range. Each target's hit point maximum and current hit points increase by 5 for the duration.</text>
    <text />
    <text>At Higher Levels: When you cast this spell using a spell slot of 3rd level or higher, a target's hit points increase by an additional 5 for each slot level above 2nd.</text>
</spell>

Here is my code so far.

private class Description extends AsyncTask<Void, Void, Void> {
    String desc;



    @Override
    protected Void doInBackground(Void... params) {
        try {
            // Connect to the web site
            Document document = Jsoup.parse(new URL(url).openStream(), "UTF-8", "", Parser.xmlParser());
            Elements elements = document.getElementsMatchingOwnText("name");
            // Using Elements to get the Meta data
            for(Element e : elements) {
                desc = desc +", "+ e;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        // Set description into TextView
        TextView txtdesc = (TextView) findViewById(R.id.desctxt);
        txtdesc.setText(desc);
    }
}

What I want this to do:

Output : Acid Splash, Aid

What it actually Outputs: Output :

<text>
This spells damage increases by 1d6 when you reach 5th Level (2d6), 11th level (3d6) and 17th level (4d6).
</text>, <text>
At Higher Levels: When you cast this spell using a spell slot of 3rd level or higher, a target's hit points increase by an additional 5 for each slot level above 2nd.
</text>

Upvotes: 1

Views: 3607

Answers (1)

Pshemo
Pshemo

Reputation: 124275

getElementsMatchingOwnText tries to find element based on its own text, like when you want to find <name>Foo Bar</name> based on Foo or Bar. Instead use

  • select which supports CSS query format,
  • or document.getElementsByTag("name")

Also to actually get text which element represent call e.text().

BTW you shouldn't be building strings in loop via concatenation. In each iteration this needs to create new string by copying old result (which can be long) and add some small part to it. Instead use StringBuilder and append new content to it (this class is wrapper for char[] array of quite big size so append just fills it with text, when length of array is not enough it is being replaced by array with doubled size). When you are done, call toString method to get result as String.

So what you want is more like

Elements elements = document.getElementsByTag("name");
StringBuilder sb = new StringBuilder();
for(Element e : elements) {
    sb.append(e.text()).append(", ");
}
desc = sb.toString();

Upvotes: 5

Related Questions