Get tag attribute values, based on value of one attribute in xml
I 开发者_高级运维am making an application for android and am pulling and parsing the value of tag attributes from a xml file that is online. Say the xml file looks like this.
<a>
<b>
<c id="00001" time="1:00" day="Friday" name1="John" name2="Mary"></c>
<c id="00002" time="2:00" day="Monday" name1="Ed" name2="Kate"></c>
<c id="00003" time="3:00" day="Sunday" name1="Mary" name2="Ed"></c>
<c id="00004" time="4:00" day="Friday" name1="Kate" name2="John"></c>
</b>
</a>
The app will have a set name to it (ex. John, Ed, Mary, Kate) and I would like to pull the values of the tag attributes for whichever line the name appears in and which attribute the name is in (ex. name1, name2), the name will stay the same but it will shift lines and attribute depending on the week.
I have searched for the answer and have found that I will most likely be using XPath. Can anyone help me with how I would make this happen? Does my parsing method matter to use xpath? DOM or SAX?
Thanks in advance!
The package documentation for javax.xml.xpath
gives a nice introduction, but here's some example code, too:
InputSource xml = new InputSource(new StringReader("<a>\n" +
"<b>\n" +
"<c id=\"00001\" time=\"1:00\" day=\"Friday\" name1=\"John\" name2=\"Mary\"></c>\n" +
"<c id=\"00002\" time=\"2:00\" day=\"Monday\" name1=\"Ed\" name2=\"Kate\"></c>\n" +
"<c id=\"00003\" time=\"3:00\" day=\"Sunday\" name1=\"Mary\" name2=\"Ed\"></c>\n" +
"<c id=\"00004\" time=\"4:00\" day=\"Friday\" name1=\"Kate\" name2=\"John\"></c>\n" +
"</b>\n" +
"</a>"));
So no SAX, but any DOM InputSource
will do. After that it's:
String name = "John";
XPath xpath = XPathFactory.newInstance().newXPath();
// the String.format is just here so you can see the XPath expression more
// clearly without all the ".."+x+".." string concat, feel free to replace
String expr = String.format("//a/b/c[@name1='%s']", name);
Node c = (Node) xpath.evaluate(expr, xml, XPathConstants.NODE);
NamedNodeMap attribs = c.getAttributes();
String id = attribs.getNamedItem("id").getNodeValue();
String time = attribs.getNamedItem("time").getNodeValue();
// etc.
If the element name c
is unique in the whole document, you can cut down the XPath expression to //c[@name1='%s']
.
If you need to match against both of name1
and name2
use this node test instead: [@name1='%s' or @name2='%s']
. In this case you'll probably also need to get a NodeList
from evaluate()
to handle multiple matches:
NodeList c = (NodeList) xpath.evaluate(expr, xml, XPathConstants.NODESET);
The answer abover, regarding xpath is probably the best way to go. However, if you wanted to actually create POJOs from the xml graph, you could deserialize the xml using something like XStream, or in more complicated xml structures, you could create a schema from the xml using Trang, and then create java classes using the jaxb xjc tool.
Using your example, I wrote a little program that shows how you could do it using XStream: You can get the binary or source distribution for XStream here: http://x-stream.github.io/download.html
There are some easy examples on the site, and they say it works on the Android.
Here's my code:
package misc;
import java.io.Reader;
import java.io.StringReader;
import java.util.List;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
public class ProcessMyXml {
@XStreamAlias("c")
public static class c{
//<c id="00001" time="1:00" day="Friday" name1="John" name2="Mary"></c>
@XStreamAsAttribute
String time;
@XStreamAsAttribute
String day;
@XStreamAsAttribute
String name1;
@XStreamAsAttribute
String name2;
@Override
public String toString() {
return time+","+day+","+name1+","+name2;
}
}
public static class bClass{
@XStreamImplicit
List<c> cList;
}
@XStreamAlias("a")
public static class a{
bClass b;
}
public static void main(String[] args) {
XStream xs = new XStream();
xs.processAnnotations(a.class);
Reader reader = new StringReader("<a>\n" +
"<b>\n" +
"<c id=\"00001\" time=\"1:00\" day=\"Friday\" name1=\"John\" name2=\"Mary\"></c>\n" +
"<c id=\"00002\" time=\"2:00\" day=\"Monday\" name1=\"Ed\" name2=\"Kate\"></c>\n" +
"<c id=\"00003\" time=\"3:00\" day=\"Sunday\" name1=\"Mary\" name2=\"Ed\"></c>\n" +
"<c id=\"00004\" time=\"4:00\" day=\"Friday\" name1=\"Kate\" name2=\"John\"></c>\n" +
"</b>\n" +
"</a>");
a aFromFile = (a)xs.fromXML(reader);
List<c> cList = aFromFile.b.cList;
for(c current_c:cList){
System.out.println(current_c.toString());
}
}
}
精彩评论