问题
So I have done a few "minor" things with web services and had some success, but when I attempted to tinker around with some stuff for fun I was encountering what I believe is me incorrectly parsing out the data to get the information that I need. I can get the entire xml as a string but not just the 3 programs that I need. The getPrograms and getInstitutions are similar enough that if I can get the programs part parsed right I can get the institutions. Where I am getting confused is what I believe is the "tags" and how much they differ from any tutorials to what I am actually using. I also went the way of the XmlPullParser but do not know if this is the best way about doing this (is it?). The format of what I am accessing is as follows:
<DataSet>
<xs:schema id="NewDataSet">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="tblPrograms">
<xs:complexType>
<xs:sequence>
<xs:element name="Program" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram>
<NewDataSet>
<tblPrograms diffgr:id="tblPrograms1" msdata:rowOrder="0">
<Program>Ancillary</Program>
</tblPrograms>
<tblPrograms diffgr:id="tblPrograms2" msdata:rowOrder="1">
<Program>Ancillary ESY</Program>
</tblPrograms>
<tblPrograms diffgr:id="tblPrograms3" msdata:rowOrder="2">
<Program>REAP</Program>
</tblPrograms>
</NewDataSet>
</diffgr:diffgram>
</DataSet>
And my source code is as follows:
public class FirstScreen extends Activity {
/** Called when the activity is first created. */
private static final String NAMESPACE = "http://tempuri.org/";
private static final String URL = "http://www.ces.org/android/android.asmx";//must point to where service is located
/** HelloAndroid method */
//SOAP_ACTION = NAMESPACE + METHODNAME
private static final String SOAP_ACTION = "http://tempuri.org/HelloAndroid";
private static final String METHOD_NAME = "HelloAndroid";
/** SelectInstitutionTypes method */
//SOAP_ACTION = NAMESPACE + METHODNAME
private static final String SOAP_ACTION_INSTITUTIONS = "http://tempuri.org/SelectInstitutionTypes";
private static final String METHOD_NAME_INSTITUTIONS = "SelectInstitutionTypes";
/** SelectPrograms method */
//SOAP_ACTION = NAMESPACE + METHODNAME
private static final String SOAP_ACTION_PROGRAMS = "http://tempuri.org/SelectPrograms";
private static final String METHOD_NAME_PROGRAMS = "SelectPrograms";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getHelloAndroid();
//getInstitutionTypes();
getPrograms();
}//end of onCreate
private void getPrograms() {
TextView tv3 = (TextView)findViewById(R.id.TextView03);//contains SelectInstitutionTypes information
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME_PROGRAMS);
//soap serialization
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);//running 1.1
soapEnvelope.dotNet=true;//to handle .net services asmx/aspx
soapEnvelope.setOutputSoapObject(request);//package request
//create transport object(s)
HttpTransportSE aht = new HttpTransportSE(URL);
try
{
aht.debug = true;
//make the call
aht.call(SOAP_ACTION_PROGRAMS, soapEnvelope); //in/out
SoapObject resultString = (SoapObject)soapEnvelope.getResponse();
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new StringReader (resultString.toString()));
int eventType = xpp.getEventType();
while(eventType != XmlPullParser.END_DOCUMENT){
if(eventType == XmlPullParser.START_DOCUMENT) {
System.out.println("Start document");
} else if(eventType == XmlPullParser.START_TAG) {
if(xpp.getName().equals("Program"))
System.out.println("Start tag "+xpp.getName());
System.out.println("Program"+ xpp.getAttributeName(0));
} else if(eventType == XmlPullParser.END_TAG) {
System.out.println("End tag "+xpp.getName());
} else if(eventType == XmlPullParser.TEXT) {
System.out.println("Text "+xpp.getText());
}
eventType = xpp.next();
}
System.out.println("End document");
tv3.setBackgroundColor(Color.BLUE);
tv3.setText("STATUS: " + resultString /*ks.toString()*/ + "\n\n" + "AHTHOST: " +
aht.getHost() + "\n\n" + "NAHT STRING: " + aht.toString());
}
catch(Exception e)
{
e.toString();
e.printStackTrace();
tv3.setText("EXCEPTION NAME: " + e.toString().toString() +
"\n\n" + "EXCEPTION MESSAGE: " + e.getMessage() + " ");
}
}//end of getPrograms
private void getInstitutionTypes() {
TextView tv2 = (TextView)findViewById(R.id.TextView02);//contains SelectInstitutionTypes information
//tv2.setText("TODO: SelectInstitutionTypes");
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME_INSTITUTIONS);
//soap serialization
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);//running 1.1
soapEnvelope.dotNet=true;//to handle .net services asmx/aspx
soapEnvelope.setOutputSoapObject(request);//package request
//create transport object(s)
HttpTransportSE aht = new HttpTransportSE(URL);
try
{
aht.debug = true;
//make the call
aht.call(SOAP_ACTION_INSTITUTIONS, soapEnvelope); //in/out
SoapObject resultString = (SoapObject)soapEnvelope.getResponse();
tv2.setText("STATUS: " + resultString /*ks.toString()*/ + "\n\n" + "AHTHOST: " +
aht.getHost() + "\n\n" + "NAHT STRING: " + aht.toString());
}
catch(Exception e)
{
e.toString();
e.printStackTrace();
tv2.setText("EXCEPTION NAME: " + e.toString().toString() +
"\n\n" + "EXCEPTION MESSAGE: " + e.getMessage() + " ");
}
}//end of getInstitutionTypes
public void getHelloAndroid() {
TextView tv = (TextView)findViewById(R.id.TextView01);//contains HelloAndroid information
SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
//soap serialization
SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);//running 1.1
soapEnvelope.dotNet=true;//to handle .net services asmx/aspx
soapEnvelope.setOutputSoapObject(request);//package request
//create transport object(s)
HttpTransportSE aht = new HttpTransportSE(URL);
try
{
aht.debug = true;
//make the call
aht.call(SOAP_ACTION, soapEnvelope); //in/out
SoapPrimitive resultString = (SoapPrimitive)soapEnvelope.getResponse();
tv.setBackgroundColor(Color.BLUE);
tv.setText("STATUS: " + resultString + "\n\n" + "AHTHOST: " +
aht.getHost() + "\n\n" + "NAHT STRING: " + aht.toString());
}
catch(Exception e)
{
e.toString();
e.printStackTrace();
tv.setText("EXCEPTION NAME: " + e.toString().toString() +
"\n\n" + "EXCEPTION MESSAGE: " + e.getMessage() + " ");
}
}//end of getHelloAndroid
}//end of activity
回答1:
So after much research I was able to get this parsed correctly so I figured I would answer my own question. I also had to change the structure of my program to get what I needed...or at least understand what I was doing before I started to implement it in the code above. So the 3 classes that are below are the ones I used to get what I needed...for now.
public class MyXMLHandler extends DefaultHandler {
Boolean currentElement = false;
String currentValue = null;
public static ProgramList programList = null;
public static ProgramList getProgramList() {
return programList;
}
public static void setProgramList(ProgramList programList) {
MyXMLHandler.programList = programList;
}
//called when tag starts ( ex:- <tblPrograms>diffgr:id="tblPrograms1" msdata:rowOrder="0"</tblPrograms> -- <tblPrograms> )
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
currentElement = true;
//set up for hierarchy scan to place data within category
if (localName.equals("DataSet"))
{
/** Start */
programList = new ProgramList();
} else if (localName.equals("tblPrograms")){//"NewDataSet" - DOES NOT WORK - F.C.
/** Get attribute value */
String attr = attributes.getValue(0);
String attr2 = attributes.getValue(1);
programList.setTable(attr);
programList.setRowOrder(attr2);
}
}
//called when tag closing ( ex:- <Program>Ancillary</Program> -- </Program> )
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
currentElement = false;
/** set value */
if (localName.equalsIgnoreCase("Program"))
programList.setProgram(currentValue);
//else if (localName.equalsIgnoreCase("tblPrograms"))
//programList.setWebsite(currentValue);
}
//called to get tag characters ( ex:- <Program>Ancillary</Program> -- to get Ancillary character )
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (currentElement) {
currentValue = new String(ch, start, length);
currentElement = false;
}
}
}
Then I have my getter and setter methods for the variables within my program list.
//contains getter and setter method for variables
public class ProgramList {
//variables
private ArrayList<String> program = new ArrayList<String>();
private ArrayList<String> rowOrder = new ArrayList<String>();
private ArrayList<String> table = new ArrayList<String>();
//in Setter method default it will return arraylist change that to add
public ArrayList<String> getProgram() {
return program;
}
public void setProgram(String program) {
this.program.add(program);
}
public ArrayList<String> getRowOrder() {
return rowOrder;
}
public void setRowOrder(String rowOrder) {
this.rowOrder.add(rowOrder);
}
public ArrayList<String> getTable() {
return table;
}
public void setTable(String table) {
this.table.add(table);
}
}
Finally main
public class XMLParsingExample extends Activity {
//create object For SiteList class
ProgramList programList = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//create a new layout to display the view
//LinearLayout layout = new LinearLayout(this);
//layout.setOrientation(1);
LinearLayout ll = (LinearLayout)findViewById(R.id.LL01);
//create a new textview array to display the results
//TextView name[];
//TextView website[];
//TextView category[];
try {
//handle XML
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
//URL to parse XML Tags
URL sourceUrl = new URL(
"http://www.ces.org/android/android.asmx/SelectPrograms");
//Create handler to handle XML Tags ( extends DefaultHandler )
MyXMLHandler myXMLHandler = new MyXMLHandler();
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
//get result from MyXMLHandler SitlesList Object
programList = MyXMLHandler.programList;
//assign a textview array length by arraylist size
TextView name[] = new TextView[programList.getProgram().size()];
TextView website[] = new TextView[programList.getProgram().size()];
TextView category[] = new TextView[programList.getProgram().size()];
//set the result text in textview and add it to layout
for (int i = 0; i < programList.getProgram().size(); i++) {
name[i] = new TextView(this);
name[i].setText("Program = "+programList.getProgram().get(i));
name[i].setBackgroundColor(Color.BLUE);
website[i] = new TextView(this);
website[i].setText("Row Order = "+programList.getRowOrder().get(i));
category[i] = new TextView(this);
category[i].setText("Program Table = "+programList.getTable().get(i));
//layout.addView(name[i]);
//layout.addView(website[i]);
//layout.addView(category[i]);
ll.addView(name[i]);
ll.addView(website[i]);
ll.addView(category[i]);
}
//set the layout view to display
//setContentView(layout);
setContentView(ll);
}
}
来源:https://stackoverflow.com/questions/5462399/android-and-net-webservice-parsing-the-returned-xml