Sample of the xml:
<name>item1</name>
<reference_id>100</reference_id> -->notice of the duplicate reference id
<name>item 2</name>
<reference_id>200</reference_id>
<name>item 3</name>
<reference_id>100</reference_id> -->notice of the duplicate reference id
<name>item 4</name>
<reference_id>400</reference_id>
I have a large xml file which I use SAX Parser to extract data according to the element tag but since SAX Parser does not follow hierachy and each element attribute or tag is purely identified and added in the respective arraylist.
Current Output:
name: [item 1, item 2, item 3, item 4]
reference_id :[100, 200, 100, 400]
Current Problem:
I want to create a method when user inputs a keyword and is able to display the result.
E.g if user enters item 1 as the keyword, my idea is to get the position of the keyword in name arraylist and retreive the same position from arraylist reference id since it is one to one match. So in this case is name[0] = reference_id[0].
But the problem is when I do a filtering of the reference id as keyword. How can reference id tells which name it is linked to? Supposely if all reference id is distinct, there should not have any problem. But notice there is duplicated id. How should I go about doing it?
There are two concepts you can apply for this.
You can parse your XML using a handler, as the handler process each node you will need to build the objects you want using the start and end element methods.
public class Name
{
private String name = null;
private String value = null;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getValue()
{
return value;
}
public void setValue(String value)
{
this.value = value;
}
}
public class NameHandler extends DefaultHandler
{
private ArrayList<Name> nameList;
private Name name = null;
private boolean nameTag = false;
private boolean valueTag = false;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException
{
if (qName.equalsIgnoreCase("name"))
{
name = new Name();
nameTag = true;
}
if (qName.equalsIgnoreCase("reference_id"))
{
valueTag = true;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
{
if (qName.equalsIgnoreCase("name"))
{
//add Name object to list
nameList.add(name);
}
}
@Override public void characters(char[] ch, int start, int length) throws SAXException
{
String theValue = new String(ch, start, length);
if (nameTag)
{
name.setName(theValue);
nameTag = false;
}
if (valueTag)
{
name.setValue(theValue);
valueTag= false;
}
}
public ArrayList<Name> getNameList()
{
return nameList;
}
}
the code to call all of this is simply
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
NameHandler handler = new NameHandler();
saxParser.parse(XML,handler);
NOTE this is NOT SAX
The XML path can be built and supped by the input being
String expression = "/root[name='item 2']/reference_id";
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
Note completely untested code