Search code examples
javaxmlxpathvtd-xml

XPath on log4j.xml using VTD-XML


I have validLog4jXML String like this

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<!DOCTYPE log4j:eventSet PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd" >
<log4j:eventSet version="1.2" xmlns:log4j="http://jakarta.apache.org/log4j/" includesLocationInfo="true">
    <log4j:event logger="org.apache.axis2.deployment.ClusterBuilder" 
        timestamp="1395925603261" level="INFO" thread="localhost-startStop-1">
        <log4j:message>
            <![CDATA[Clustering has been disabled]]>
        </log4j:message>
    </log4j:event>
</log4j:eventSet>

I try to run this code:

VTDGen doc = new VTDGen();
doc.setDoc(validLog4jXML.getBytes());
doc.parse(true);
VTDNav vn = doc.getNav();
AutoPilot ap = new AutoPilot(vn);
String xPath = "//log4j:event[(((@level=\"INFO\") or (@level=\"ERROR\")) and "
            + "(@timestamp>\"1395842943674\")) and (@timestamp<\"1396015743674\")]";
ap.selectXPath(xPath);

On this last line i get exception:

[ERROR] No URL found for prefix:log4j
com.ximpleware.XPathParseException: No URL found for prefix:log4j
    at com.ximpleware.xpath.CUP$parser$actions.CUP$parser$do_action(parser.java:752)
    at com.ximpleware.xpath.parser.do_action(parser.java:434)
    at java_cup.runtime.lr_parser.parse(lr_parser.java:570)
    at com.ximpleware.AutoPilot.selectXPath(AutoPilot.java:809)
    at ad.ecs.library.LogHelper.collectLogNodesVTD(LogHelper.java:654)
    at ad.ecs.library.LogHelper.collectLogNodesForADayVTD(LogHelper.java:571)
    at ad.ecs.library.LogHelper.collectLogNodesForTheWeekVTD(LogHelper.java:456)
    at ad.ecs.library.LogHelper.access$2(LogHelper.java:453)
    at ad.ecs.library.LogHelper$2.run(LogHelper.java:313)
    at java.lang.Thread.run(Thread.java:724)

I tried to look at documentation on VTD-XML and it said:

To avoid this exception:

com.ximpleware.XPathParseException: No URL found for prefix:xyz

Be sure to create the initial navigator object with namespace support (that is, with the last param set to true), and to pass in the namespace hash as the final param to find-indexes, first-match, all-matches, get-xml, and get-hash.

I poked around trying to follow these steps but was unsuccessful. I would appreciate any help.


Solution

  • You must register the namespace before using it in the query using declareXPathNameSpace:

    ap.declareXPathNameSpace(log4j, "http://jakarta.apache.org/log4j/");