1

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;"

1
  • 1
    what xml parser you want to use? Commented Feb 12, 2013 at 5:29

2 Answers 2

1

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'
Sign up to request clarification or add additional context in comments.

5 Comments

wait some minutes and i try to write sax
I use JRE 1.6, the switch case using String is not permitted. Thanks for the answer.
I could get the DOM answer working with little modification. SAX is not working. Could you pls update as how to use it?
what the problem with sax?
@AlekseiBulgak - FYI, here is how it could be implemented using the javax.xml.xpath APIs: stackoverflow.com/a/14830605/383861
1

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;

2 Comments

Which of the above methods gives good performance? My project is not that complex, assuming the number of entries in the xml will not cross 50 entries.
@user1787599 - You would need to profile to find the approach that gave you optimal performance. In terms of readability and maintainability of the code the javax.xml.xpath approach is the clear winner. Note the DOM/SAX approaches count on there never being an element called queries or query anywhere else in the document ever, the XPath approach ensures you always get what you want.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.