単純なJavaパーサーが役立ちます。
import java.util.Vector;
/**
* XMLSimpleTouch is a simple xml parser, it allow to retrive only tags bodies.
*
* Example XML file (in exampleXmlString variable): <?xml?> <books> <book>
* <title>book1 title</title> <isbn>1122334455</isbn> </book> <book>
* <title>book2 title</title> <isbn>2233445566</isbn> </book> </books>
*
* Example of use: XMLSimpleTouch xml = new XMLSimpleTouch(exampleXmlString);
* xml.getString("books/book/title"); // return "book1 title" //NOW WE LOOK FOR
* SECOND BOOK xml.getString("books/book[2]/title"); // return "book2 title"
*
* path "books/book[1]/title" is equal: "books/book/title"
*
* TODO: 1) add attributes, 2) add parsing from stream
*/
public class XMLSimpleTouch {
private String defaultNodeValue = null;
/** XML string to parse */
private String strXML = null;
/**
* Constructor
*
* @param xml
* XML string to parse
*/
public XMLSimpleTouch(String xml) {
this.strXML = xml;
}
/**
* Retrive string value between tags from given path. XML file was given in
* constructor, default value is null.
*
* @param XMLpath
* path to string
* @return value in given path or default value if path not found
*/
public String getText(String XMLpath) {
return getText(XMLpath, null, null);
}
/**
* Retrive string value between tags from given path.
*
* @param XMLpath
* path to string
* @param defaultValue
* default value to return if path not found
* @return value in given path or default value if path not found
*/
public String getText(String XMLpath, String defaultValue) {
this.defaultNodeValue = defaultValue;
return getText(XMLpath, defaultValue, null);
}
/**
* Retrive string value between tags from given path.
*
* @param XMLpath
* path to string
* @param defaultValue
* default value to return if path not found
* @param XMLFile
* xml string to parse instead of given in constructor
* @return value in given path or default value if path not found
*/
public String getText(String XMLpath, String defaultValue, String XMLFile) {
if (strXML == null)
return null;
try {
/** Disasembly path */
Object[][] path = dissasemblyPath(XMLpath);
/** XML string to parse */
String result = strXML;
/** If given xml string is null use xml given in constructor */
if (XMLFile != null)
result = XMLFile;
/** Extract value from path */
for (int i = 0; i < path.length; i++) {
/** Get element from path */
String element = (String) path[i][0];
/** Get occurence we search */
int occurence = ((Integer) path[i][1]).intValue();
/** Extract element */
result = extractElement(element, occurence, result);
}
/** Return extracted value */
return result;
} catch (Exception e) {
}
return defaultValue;
}
/**
* Search for given element and return its body.
*
* @param element
* @param occurence
* @param xmlStr
* string where we look for element
* @return
*/
private String extractElement(String element, int occurence, String xmlStr) {
int index = 0;
String elString = null;
do {
int elNameLength = element.length() + 2;
int elStart = xmlStr.indexOf("<" + element + ">", index);
int elEnd = xmlStr.indexOf("</" + element + ">", elStart
+ elNameLength);
// returns 'defaultNodeValue' if the specifed child node(eg:
// books/book[4]) not found or none of childs are present
if (elStart == -1 || elEnd == -1)
return defaultNodeValue;
elString = xmlStr.substring(elStart + elNameLength, elEnd);
occurence--;
index = elEnd + elNameLength;
}
/** Repeat until occurence is 0 or null is given */
while (occurence > 0 && elString != null);
return elString;
}
/**
* Disassembly path to elements and its occurences
*
* @param XMLpath
* path to disassembly
* @return Object[][] array, first element in array is path element, second
* is occurence.
*/
private Object[][] dissasemblyPath(String XMLpath) {
/** Split path */
String[] str = split(XMLpath, "/");
/** Create array to keep elements and occurences */
Object[][] resultArray = new Object[str.length][2];
/** Fill array with elements from path */
for (int i = 0; i < str.length; i++) {
/** Get path piece */
String s = str[i];
String occurence = "1";
/** Search for occurence */
int occur1 = s.indexOf("[");
int occur2 = s.indexOf("]", occur1 + 1);
if (occur1 != -1 && occur2 != -1) {
/** Occurence defined */
occurence = s.substring(occur1 + 1, occur2);
resultArray[i][0] = s.substring(0, occur1);
resultArray[i][1] = new Integer(Integer.parseInt(occurence));
} else {
/** No occurence defined, using default */
resultArray[i][0] = s;
resultArray[i][1] = new Integer(1);
}
}
return resultArray;
}
public static String[] split(String source, String separator) {
Vector<String> vector = new Vector<String>();
String[] strings = null;
while (true) {
int index = source.indexOf(separator);
if (index == -1) {
vector.addElement(source);
break;
}
vector.addElement(source.substring(0, index));
source = source.substring(index + separator.length());
}
strings = new String[vector.size()];
for (int i = 0; i < vector.size(); ++i) {
strings[i] = ((String) vector.elementAt(i));
}
return strings;
}
public static void main(String[] args) {
String xml = "<questions>" +
" <question>" +
" <title>What eth speed?</title>" +
" <options>" +
" <option>10</option>" +
" <option>100</option>" +
" <option>1000</option>" +
" </options>" +
" <tagtochange>change this tag</tagtochange>" +
" </question>" +
" <question>" +
" <title>What duration?</title>" +
" <options>" +
" <option>Null</option>" +
" </options>" +
" <tagtochange>duration</tagtochange>" +
" </question>" +
"</questions>";
XMLSimpleTouch xmlParser = new XMLSimpleTouch(xml);
// traversing the first question
System.out.println(xmlParser.getText("questions/question[1]/options/option[1]"));
System.out.println(xmlParser.getText("questions/question[1]/options/option[2]"));
System.out.println(xmlParser.getText("questions/question[1]/options/option[3]"));
System.out.println(xmlParser.getText("questions/question[1]/options/option[4]")); // this will be null
// traversing the second question
System.out.println(xmlParser.getText("questions/question[2]/options/option[1]"));
System.out.println(xmlParser.getText("questions/question[2]/options/option[2]"));
System.out.println(xmlParser.getText("questions/question[2]/options/option[3]"));
System.out.println(xmlParser.getText("questions/question[2]/options/option[4]"));
}
}
境界/終了条件をnull
値として、単純なロジックを使用して繰り返すこともできます。
編集
option
すべてのタグ値を取得するための反復ロジックを追加しましたquestions
for(int i=1;;i++)
{
String value = xmlParser.getText("questions/question["+i+"]");
if(value==null)break;
for(int j=1;;j++)
{
value = xmlParser.getText("questions/question["+i+"]/options/option["+j+"]");
if(value==null)break;
System.out.println(value);
}
}