Reputation: 119
I'm working on a small app that uses and xml file to print an ArrayList of chapters which in turn points to a specific html file.
I used this tutorial to get me started: http://www.anddev.org/novice-tutorials-f8/parsing-xml-from-the-net-using-the-saxparser-t353.html
My xml file looks something like this:
<chapters>
<chapter title="Förutsättningar">
<page title="Sida 3" url="sida_3.html" />
<page title="Sida 4" url="sida_4.html" />
</chapter>
</chapters>
Using the tutorial above I've managed to output each chapter node into an ArrayList with a onListItemClick function on each item. So far so good.
The problem I'm having is that I can't figure out how to get a specific child node and load the html file when I click an item. I'm pretty new to Android.
Any ideas? I would really appreciate ANY help on the subject.
Here's my source:
ParsingXML.java
public class ParsingXML extends ListActivity {
private final String MY_DEBUG_TAG = "XmlParser";
public String lang = null;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setTitle("Lastsäkring");
Bundle bundle = this.getIntent().getExtras();
lang = bundle.getString("lang");
Log.i("ParsingXML", "Chosen language: " + this.lang + ", Type: " + this.lang.getClass().getName());
TextView tv = new TextView(this);
try {
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
ExampleHandler myExampleHandler = new ExampleHandler();
xr.setContentHandler(myExampleHandler);
/*
* If XML-file is located online (needs internet permissions in the manifest):
* URL url = new URL("http://dev.houdini.se/android/demo.xml");
* xr.parse(new InputSource(url.openStream()));
*/
if(this.lang.equals("en"))
xr.parse(new InputSource(this.getResources().openRawResource(R.raw.en_content)));
else
xr.parse(new InputSource(this.getResources().openRawResource(R.raw.sv_content)));
ParsedExampleDataSet parsedExampleDataSet = myExampleHandler.getParsedData();
this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, parsedExampleDataSet.toArrayList()));
} catch(Exception e) {
tv.setText("Error: " + e.getMessage());
Log.e(MY_DEBUG_TAG, "XmlParseError", e);
this.setContentView(tv);
}
}
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Context context = getApplicationContext();
int duration = Toast.LENGTH_SHORT;
CharSequence text = "Clicked position: " + position + ", id: " + id;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
/*switch( position )
{
case 0:
Bundle bundle = new Bundle();
bundle.putString("WindowTitle", "TESTA");
Intent intent = new Intent(this, TextPage.class);
intent.putExtras(bundle);
startActivity(intent);
break;
case 1:
Intent video = new Intent(this, Video.class);
startActivity(video);
break;
case 2:
Intent swipe = new Intent(this, Swipe.class);
startActivity(swipe);
break;
}*/
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.settings:
Intent prefsActivity = new Intent(getBaseContext(), Preferences.class);
startActivity(prefsActivity);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
ExampleHandler.java
public class ExampleHandler extends DefaultHandler {
private boolean in_chapters = false;
private boolean in_chapter = false;
private boolean in_page = false;
private ParsedExampleDataSet myParsedExampleDataSet = new ParsedExampleDataSet();
public ParsedExampleDataSet getParsedData() {
return this.myParsedExampleDataSet;
}
@Override
public void startDocument() throws SAXException {
this.myParsedExampleDataSet = new ParsedExampleDataSet();
}
@Override
public void endDocument() throws SAXException {
// Nothing to do
}
@Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if(localName.equals("chapters")) {
this.in_chapters = true;
} else if(localName.equals("chapter")) {
this.in_chapter = true;
String attrValue = atts.getValue("title");
myParsedExampleDataSet.setExtractedString(attrValue);
} else if(localName.equals("page")) {
this.in_page = true;
}
}
@Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
if(localName.equals("chapters")) {
this.in_chapters = false;
} else if(localName.equals("chapter")) {
this.in_chapter = false;
} else if(localName.equals("page")) {
this.in_page = false;
}
}
@Override
public void characters(char ch[], int start, int length) {
if(this.in_page == true) {
myParsedExampleDataSet.setExtractedString(new String(ch, start, length));
}
}
}
ParsedExampleDataSet.java
public class ParsedExampleDataSet {
private String extractedString = "";
private ArrayList<String> myArr = new ArrayList<String>();
private int extractedInt = 0;
public ArrayList<String> getExtractedString() {
//return extractedString; Function Type = String
return myArr;
}
public void setExtractedString(String extractedString) {
//this.extractedString += extractedString + "\n";
myArr.add(extractedString);
}
public int getExtractedInt() {
return extractedInt;
}
public void setExtractedInt(int extractedInt) {
this.extractedInt = extractedInt;
}
public String toString() {
return "NODER\n" + this.extractedString;
}
public ArrayList<String> toArrayList() {
return this.myArr;
}
}
Upvotes: 3
Views: 2836
Reputation: 59168
First create proper data structure:
public class PageNode {
public String title;
public String url;
/* Getters/setter/constructor etc. if you feel like*/
public String toString() {
return title;
}
}
public class ChapterNode {
public String title;
public ArrayList<PageNode> pages = new ArrayList<PageNode>();
/* Getters/setter/constructor etc. if you feel like*/
}
And parse the xml accordingly. Example:
ArrayList<ChapterNode> chapters = new ArrayList<ChapterNode>();
ChapterNode chapterNode = null;
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
if(localName.equals("chapters")) {
} else if(localName.equals("chapter")) {
chapterNode = new ChapterNode();
chapterNode.title = atts.getValue("title");
} else if(localName.equals("page")) {
PageNode pageNode = new PageNode();
pageNode.title = atts.getValue("title");
pageNode.url = atts.getValue("url");
chapterNode.pages.add(pageNode);
}
}
@Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
if(localName.equals("chapters")) {
} else if(localName.equals("chapter")) {
chapters.add(chapterNode);
chapterNode = null;
} else if(localName.equals("page")) {
}
}
Then you can access the pageNode like this:
PageNode pageNode = chapterNode.pages.get(position);
And set adapter like this:
this.setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, chapterNode.pages));
Upvotes: 2
Reputation: 3084
I'm used to using DocumentBuilderFactory, so my solution is:
firstly, you should create ArrayHelper class like this:
public class ArrayHelper {
public static ArrayList<HashMap<String, ?>> list = new ArrayList<HashMap<String, ?>>();
}
than:
public class CoversParseTask extends AsyncTask<Void, Void, Boolean> {
@Override
protected void onPreExecute() {
}
@Override
protected Boolean doInBackground(Void ... arg0) {
try {
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
document = dBuilder.parse(new InputSource(this.getResources().openRawResource(R.raw.en_content)));
document.getDocumentElement().normalize();
NodeList nodeListIssue = document.getElementsByTagName("page");
for (int i = 0; i < nodeListIssue.getLength(); i++) {
HashMap<String, Object> temp = new HashMap<String, Object>();
Node node = nodeListIssue.item(i);
Element elementMain = (Element) node;
String pageID = elementMain.getAttribute("title");
String issueID = elementMain.getAttribute("url");
temp.put("title", pageID);
temp.put("url", issueID);
ArrayHelper.list.add(temp);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
};
return false;
}
@Override
protected void onPostExecute(Boolean result) {
//what happend if done.
}
}
and execute this class like this:
new CoversParseTask().execute();
now we must create simple adapter:
SimpleAdapter adapter = new MySimpleAdapter(this, selectLastSearch(), R.layout.custom_row_view, new String[] { "Title", "Url" }, new int[] { R.id.title, R.id.url});
and our MySimpleAdapter looks like this:
public class MySimpleAdapter extends SimpleAdapter {
Context localcontext = null;
public MySimpleAdapter(Context context,List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);
localcontext = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
return view;
}
}
noe set adapter to listview:
listview.setAdapter(adapter);
if You want to get URL from list, you should add listner to listview like this:
listview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapter, View view,
int position, long arg) {
Log.v("URL", ArrayHelper.list.get(position).get("url").toString());
}
});
and thats all, i hope that i help you :)
Upvotes: 0
Reputation: 1783
(Without having looked at the example tutorial...)
Have a look at the Attributes
parameter of startElement
in your example handler. It should contain a value for "url"
(it looks like you're only getting the value for "title"
).
Upvotes: 0
Reputation: 1932
You have to check for boolean variables while chapter tag is true you have to add pages in one arraylist and when chapter tag is false you have to add that arraylist in another gloabl arraylist
Upvotes: 0