java find value of an xml attribute
this is my xml :
<-tobject.subject tobject.subject.refnum="01016000" />
<-tobject.subject tobject.subject.refnum="10004000" />
I want to extract 01016000 and 10004000 from it .
I used this code:
NodeList nodeLst4 = doc.getElementsByTagName("tobject.subject");
if (nodeLst4 != null) {
int numberofCOdes = nodeLst4.getLength();
aSubjectCodes = new String[numberofCOdes];
for (int i = 0; i < numberofCOdes; i++) {
XPath xpath = XPathFactory.newInstance().newXPath();
aSubjectCodes[i] = xpath.evaluate("//tobject.subject/@tobject.subj开发者_StackOverflow中文版ect.refnum", doc);
the problem is that when i loop through it the evaluate method just return first number and do not give me the second value.
and i am not sure if using xpath.evaluate is good idea or not.
Thanks
there is no need to use the doc.getElementsByTagName. You are mixing plain DOM with XPath.
Your xpath is correct:
package net.davymeers;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XpathTest {
private static String XMLSTRING = "<data>"
+ "<tobject.subject tobject.subject.refnum=\"01016000\" />\r\n"
+ "\r\n"
+ "<tobject.subject tobject.subject.refnum=\"10004000\" />"
+ "</data>";
/**
* @param args
*/
public static void main(final String[] args) {
final Document doc = createDocument();
final XPath xpath = createXpath();
final NodeList nodes = findElements(
"//tobject.subject/@tobject.subject.refnum", doc, xpath);
final Collection<String> results = convertToCollection(nodes);
for (final String result : results) {
System.out.println(result);
}
}
private static Document createDocument() {
Document doc = null;
try {
final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
.newInstance();
documentBuilderFactory.setNamespaceAware(true); // never forget
// this!
final DocumentBuilder builder = documentBuilderFactory
.newDocumentBuilder();
doc = builder.parse(new ByteArrayInputStream(XMLSTRING
.getBytes("ISO-8859-1")));
} catch (final UnsupportedEncodingException exception) {
// TODO handle exception
} catch (final SAXException exception) {
// TODO handle exception
} catch (final IOException exception) {
// TODO handle exception
} catch (final ParserConfigurationException exception) {
// TODO handle exception
}
return doc;
}
private static XPath createXpath() {
final XPathFactory xpathFactory = XPathFactory.newInstance();
final XPath xpath = xpathFactory.newXPath();
return xpath;
}
private static NodeList findElements(final String xpathExpression,
final Document doc, final XPath xpath) {
NodeList nodes = null;
if (doc != null) {
try {
final XPathExpression expr = xpath.compile(xpathExpression);
final Object result = expr
.evaluate(doc, XPathConstants.NODESET);
nodes = (NodeList) result;
} catch (final XPathExpressionException exception) {
// TODO handle exception
}
}
return nodes;
}
private static Collection<String> convertToCollection(final NodeList nodes) {
final Collection<String> result = new ArrayList<String>();
if (nodes != null) {
for (int i = 0; i < nodes.getLength(); i++) {
result.add(nodes.item(i).getNodeValue());
}
}
return result;
}
}
Here's a useful class I found a while back for XMLFiles. Takes a lot of the work off of your shoulders.
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* XMLFile.java
*
* XML file object that represents an xml file and its properties. Used to
* simplify the process of reading from and writing to XML files.
*
* Derived from unknown source. Implemented on 12/03/09. Permission given to
* implement and modify code.
*/
public class XMLFile {
private String name;
private String content;
private Map<String, String> nameAttributes = new HashMap<String, String>();
private Map<String, List<XMLFile>> nameChildren = new HashMap<String, List<XMLFile>>();
private static Element rootElement(String filename, String rootName) {
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(filename);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document document = builder.parse(fileInputStream);
Element rootElement = document.getDocumentElement();
if (!rootElement.getNodeName().equals(rootName))
throw new RuntimeException("Could not find root node: "
+ rootName);
return rootElement;
} catch (Exception exception) {
throw new RuntimeException(exception);
} finally {
if (fileInputStream != null) {
try {
fileInputStream.close();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
}
/**
* @param (String) Filepath of XML File (String) Root of XML File
**/
public XMLFile(String filename, String rootName) {
this(rootElement(filename, rootName));
}
/**
* @param (Element) XML File Element
**/
private XMLFile(Element element) {
this.name = element.getNodeName();
this.content = element.getTextContent();
NamedNodeMap namedNodeMap = element.getAttributes();
int n = namedNodeMap.getLength();
for (int i = 0; i < n; i++) {
Node node = namedNodeMap.item(i);
String name = node.getNodeName();
addAttribute(name, node.getNodeValue());
}
NodeList nodes = element.getChildNodes();
n = nodes.getLength();
for (int i = 0; i < n; i++) {
Node node = nodes.item(i);
int type = node.getNodeType();
if (type == Node.ELEMENT_NODE)
addChild(node.getNodeName(), new XMLFile((Element) node));
}
}
/**
* Adds attribute to ???
*
* @param (String) Attribute Name (String) Attribute Value
**/
private void addAttribute(String name, String value) {
nameAttributes.put(name, value);
}
/**
* Adds child directory to ???
*
* @param (String) Name of New Child Directory (XMLFile) XML Documentation
* of Child
**/
private void addChild(String name, XMLFile child) {
List<XMLFile> children = nameChildren.get(name);
if (children == null) {
children = new ArrayList<XMLFile>();
nameChildren.put(name, children);
}
children.add(child);
}
public String name() {
return name;
}
public String content() {
return content;
}
/**
*
**/
public XMLFile child(String name) {
List<XMLFile> children = children(name);
if (children.size() != 1)
throw new RuntimeException("Could not find individual child node: "
+ name);
return children.get(0);
}
/**
*
**/
public List<XMLFile> children(String name) {
List<XMLFile> children = nameChildren.get(name);
return children == null ? new ArrayList<XMLFile>() : children;
}
/**
* Gets the value of a specific field and converts it to a String object
*
* @param (String) Name of Field
**/
public String string(String name) {
String value = nameAttributes.get(name);
if (value == null)
throw new RuntimeException("Could not find attribute: " + name
+ ", in node: " + this.name);
return value;
}
/**
* Gets the value of a specific field and converts it to an int
*
* @param (String) Name of Field
**/
public int integer(String name) {
return Integer.parseInt(string(name));
}
/**
* Gets the value of a specific field and converts it to an
* ArrayList<String>
*
* @param (String) Name of Field
**/
public ArrayList<String> arrayListString(String name) {
String left = new String();
int finished = 0;
ArrayList<String> list = new ArrayList<String>();
try {
left = nameAttributes.get(name);
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
}
while (finished == 0) {
if (left.indexOf(", ") > -1) {
list.add(left.substring(0, left.indexOf(", ")));
left = left.substring(left.indexOf(", ") + 2);
} else {
list.add(left);
finished = 1;
}
}
return list;
}
}
Would this work for you? I am parsing RSS XML from here:
http://www.kraftfoods.com/rss/dinnerRecipes.aspx
Look at Media and URL towards the bottom:
package recipeSearchAndFinder.xml;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DomFeedParser extends BaseFeedParser {
public DomFeedParser(String feedUrl) {
super(feedUrl);
}
public List<Message> parse() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
List<Message> messages = new ArrayList<Message>();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document dom = builder.parse(this.getInputStream());
Element root = dom.getDocumentElement();
NodeList items = root.getElementsByTagName(ITEM);
for (int i = 0; i < items.getLength(); i++) {
Message message = new Message();
Node item = items.item(i);
NodeList properties = item.getChildNodes();
for (int j = 0; j < properties.getLength(); j++) {
Node property = properties.item(j);
String name = property.getNodeName();
if (name.equalsIgnoreCase(TITLE)) {
message.setTitle(property.getFirstChild()
.getNodeValue());
} else if (name.equalsIgnoreCase(LINK)) {
message.setLink(property.getFirstChild().getNodeValue());
} else if (name.equalsIgnoreCase(DESCRIPTION)) {
StringBuilder text = new StringBuilder();
NodeList chars = property.getChildNodes();
for (int k = 0; k < chars.getLength(); k++) {
text.append(chars.item(k).getNodeValue());
}
message.setDescription(text.toString());
} else if (name.equalsIgnoreCase(PUB_DATE)) {
message.setDate(property.getFirstChild().getNodeValue());
} else if (name.equalsIgnoreCase(MEDIA)) {
NamedNodeMap nMap = property.getAttributes();
String mediaurl = nMap.getNamedItem("url")
.getNodeValue();
message.setMedia(mediaurl);
}
}
messages.add(message);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return messages;
}
}
精彩评论