Reputation: 2001
I would like to get the text inside an element that has two attributes, the sample xml is as below
<?xml version="1.0" encoding="UTF-8"?>
<queries>
<query pagename="master" param="default">
SELECT * from test;
</query>
<query pagename="uftl" param="default">
SELECT uftl, lop from dwells where lop='a'
</query>
</queries>
Input: two attributes, output: the query. i.e, on giving the input as 'master','default' I would like to get the query for that element, in this case 'SELECT * from test;"
Upvotes: 1
Views: 286
Reputation: 149037
Below is an example of how you could implement this use case using the javax.xml.xpath
APIs in the JDK/JRE.
import javax.xml.namespace.QName;
import javax.xml.xpath.*;
import org.xml.sax.InputSource;
public class Demo {
public static void main(String[] args) throws Exception {
// Your query can be expressed as the following XPath. It contains to
// variables $pagename and $param that we can use to inject different
// values into.
String expression = "/queries/query[@pagename=$pagename and @param=$param]";
XPathFactory xpf = XPathFactory.newInstance();
XPath xPath = xpf.newXPath();
// We will use an instance of `XPathVariableResolver` to put the real
// values into our XPath expression
xPath.setXPathVariableResolver(new XPathVariableResolver() {
@Override
public Object resolveVariable(QName variableName) {
if("pagename".equals(variableName.getLocalPart())) {
return "master";
} else if("param".equals(variableName.getLocalPart())) {
return "default";
}
return null;
}
});
InputSource source = new InputSource("src/forum14825994/input.xml");
// When we execute the XPath we can ask that the result be returned to
// us as a String
String result = (String) xPath.evaluate(expression, source, XPathConstants.STRING);
System.out.println(result);
}
}
Output
SELECT * from test;
Upvotes: 1
Reputation: 6208
oh. i write dom parser while waiting your answer
private String parse(Document document) {
Element root = document.getDocumentElement();
NodeList queries = root.getElementsByTagName("queries");
int queriesLength = queries.getLength();
for (int i = 0; i < queriesLength; i++) {
Element currentQuery = (Element) queries.item(i);
if (currentQuery.getNodeType() == Element.ELEMENT_NODE) {
String pagename = currentQuery.getAttributes()
.getNamedItem("pagename").getTextContent();
String param = currentCategory.getAttributes()
.getNamedItem("param").getTextContent();
if(param.equals(paramValue) && pagename.equals(pagename)){
String query = currnetNode.item(0).getTextContent();
return query;
}
return null;
}
}
}
SAX parser:
public class parser implements ContentHandler {
boolean check = false;
ArrayList<String> queries = new ArrayList<>();
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
switch (localName) {
case "query":
String param = atts.getValue("param");
String pagename = atts.getValue("pagename");
check = true;
break;
default:
return;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
check = false;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String tagContent = new String(ch, start, length).trim();
if(check){
if(!tagContent.isEmpty()){
queries.add(tagContent);
}
}
}
i delete sum overriden method because they was empty and unneccesary here. you must implement them and leave empty
UPDATE:
class main:
public class Main {
public static void main(String[] args) throws IOException, SAXException {
ArrayList<String> queries = new parser().getQueries("test.xml");
for (String query : queries){
System.out.println(query);
}
}
}
parser class:
public class parser implements ContentHandler {
boolean check = false;
ArrayList<String> queries = new ArrayList<>();
public ArrayList<String> getQueries(String fileName) throws SAXException, IOException {
XMLReader xmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setContentHandler(this);
xmlReader.parse(fileName);
return queries;
}
@Override
public void setDocumentLocator(Locator locator) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void startDocument() throws SAXException {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void endDocument() throws SAXException {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
switch (localName) {
case "query":
String param = atts.getValue("param");
String pagename = atts.getValue("pagename");
if(!param.isEmpty() && !pagename.isEmpty())
check = true;
break;
default:
return;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
check = false;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String tagContent = new String(ch, start, length).trim();
if(check){
if(!tagContent.isEmpty()){
queries.add(tagContent);
}
}
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void skippedEntity(String name) throws SAXException {
//To change body of implemented methods use File | Settings | File Templates.
}
}
also I add xml file in root of project with te name test.xml
my output look like this:
SELECT * from test;
SELECT uftl, lop from dwells where lop='a'
Upvotes: 1