I am tying to get child node value:
My XML file:
<url-mappings>
<url-mapping url="/screen1">
<request-handler-class>com.mappingtool.rh.Screen1RH</request-handler-class>
</url-mapping>
<url-mapping url="/screen2">
<request-handler-class>com.mappingtool.rh.Screen2RH</request-handler-class>
</url-mapping>
</url-mappings>
My Code is this:
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class MappingTool {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(new File("src/com/mappingtool/requestmapping.xml"));
NodeList nodeList = document.getElementsByTagName("url-mapping");
XPath xpath = XPathFactory.newInstance().newXPath();
for(int x=0,size= nodeList.getLength(); x<size; x++) {
System.out.println(nodeList.item(x).getAttributes().getNamedItem("url").getNodeValue());
//System.out.println(nodeList.item(x).getChildNodes().item(0));
//XPathExpression expr = xpath.compile("/request-handler-class/text()");
XPathExpression expr = xpath.compile("/url-mappings/url-mapping/request-handler-class/text()");
//XPathExpression expr = xpath.compile("/url-mappings/url-mapping["+ x +"]/request-handler-class/text()");
String rhClass = (String)expr.evaluate(nodeList.item(x), XPathConstants.STRING);
System.out.println(rhClass);
}
}
}
I am getting output
/screen1
com.mappingtool.rh.Screen1RH
/screen2
com.mappingtool.rh.Screen1RH
But I need
/screen1
com.mappingtool.rh.Screen1RH
/screen2
com.mappingtool.rh.Screen2RH
You can use expression like
XPathExpression expr = xpath.compile("/url-mappings/url-mapping[contains(#url,'"+nodeValue+"')]/request-handler-class/text()"); where nodeValue is value printed by first System.out.println.
Related
I am quite new to XML and Saxon API's, Here I am using Saxon 10.3 HE jar to extract the data from the XML file. Here I want to extract the country attribute from the active country_information node where I am using the date functions.
Sample input XML :
<person xmlns="urn:my.poctest.com">
<country_information>
<country>FRA</country>
<end_date>9999-12-31</end_date>
<start_date>2009-12-01</start_date>
</country_information>
<country_information>
<country>FRA</country>
<end_date>9999-12-31</end_date>
<start_date>2009-12-01</start_date>
</country_information>
</person>
Code :
import java.io.IOException;
import java.io.StringReader;
import java.util.Iterator;
import java.util.Map;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathFactoryConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import net.sf.saxon.xpath.XPathFactoryImpl;
public class SaxonPoc {
public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException,
XPathExpressionException, XPathFactoryConfigurationException {
String xml = " <person xmlns=\"urn:my.poctest.com\">\r\n"
+ " <country_information>\r\n"
+ " <country>FRA</country>\r\n"
+ " <end_date>9999-12-31</end_date>\r\n"
+ " <start_date>2020-02-24</start_date>\r\n"
+ " </country_information>\r\n"
+ " <country_information>\r\n"
+ " <country>USA</country>\r\n"
+ " <end_date>2020-02-23</end_date>\r\n"
+ " <start_date>2009-12-01</start_date>\r\n"
+ " </country_information> \r\n"
+ " </person>";
Document doc = SaxonPoc.getDocument(xml, false);
NodeList matches = (NodeList) SaxonTest.getXpathExpression("//person", null).evaluate(doc,
XPathConstants.NODESET);
if (matches != null) {
Element node = (Element) matches.item(0);
XPath xPath1 = SaxonPoc.getXpath(null);
String xPathStatement = "/person/country_information[xs:date(start_date) le current-date() and xs:date(end_date) ge current-date()]/country";
NodeList childNodes = (NodeList) xPath1.evaluate(xPathStatement, node, XPathConstants.NODESET);
if (childNodes.getLength() > 0) {
String nodeName = childNodes.item(0).getFirstChild().getNodeName();
System.out.println("Node :" + nodeName);
String value = childNodes.item(0).getTextContent();
System.out.println("Country Name :" + value);
}
}
System.out.println("Finished");
}
public static Document getDocument(String xml, boolean isNamespaceAware)
throws SAXException, IOException, ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(isNamespaceAware);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
return builder.parse(is);
}
public static XPath getXpath(Map<String, String> namespaceMappings) throws XPathFactoryConfigurationException {
XPathFactory xpathFactory = new XPathFactoryImpl();
XPath xpath = xpathFactory.newXPath();
NamespaceContext nsc = new NamespaceContext() {
#Override
public String getNamespaceURI(String prefix) {
return (null != namespaceMappings) ? namespaceMappings.get(prefix) : null;
}
#Override
public String getPrefix(String namespaceURI) {
return null;
}
#Override
public Iterator getPrefixes(String namespaceURI) {
return null;
}
};
xpath.setNamespaceContext(nsc);
return xpath;
}
public static XPathExpression getXpathExpression(String xpathExpr, Map<String, String> namespaceMappings)
throws XPathExpressionException, XPathFactoryConfigurationException {
XPath xpath = getXpath(namespaceMappings);
return xpath.compile(xpathExpr);
}
}
I am facing a null pointer as it is not able to find the root node person an XML doc. If I remove the xmlns="urn:my.poctest.com" then it is able to get the root path but in a later stage, it is failing with javax.xml.xpath.XPathExpressionException: net.sf.saxon.trans.XPathException: Namespace prefix 'xs' has not been declared. If I remove the namespace from XML doc and NamespaceContext implementation from code then it is working fine. But here actually I don't want to remove both things.
Can someone point out me here, what I am doing wrong? Thanks in advance!!
You might like to know that recent versions of Saxon include the option to do
((net.sf.saxon.xpath.XPathEvaluator)XPath).getStaticContext()
.setUnprefixedElementMatchingPolicy(
UnprefixedElementMatchingPolicy.ANY_NAMESPACE))
which causes an unprefixed element name in your XPath expression to match on local name alone, regardless of the namespace.
This was mainly introduced for HTML, where there is complete confusion as to whether elements in an HTML DOM are in a namespace or not; but it's useful more generally where you really don't care about the namespaces and just wish they weren't there to make your life a misery.
My objective is to Create Reusable xml parsing class concerning that return type could be array or arraylist
My code is working but I wanted reusablity I am unable to create reusable class/method due to return type which could array or arraylist is not working.**
1) I have created a xml file as follows:
<SearchStrings>
<Search id="1111" type="high">
<Questions>What is software Testing?</Questions>
<Tips>How to connect database with eclipse ?</Tips>
<Multiple>Who was the first prime minister of India? </Multiple>
<Persons>Who is Dr.APJ Abdul Kalam </Persons>
</Search>
<Search id="2222" type="low">
<Questions>What is Automation Testing?</Questions>
<Tips>How to use selenium webdriver </Tips>
<Multiple>Who was the fourth prime minister of India? </Multiple>
<Persons>Who is Superman? </Persons>
</Search>
<Search id="3333" type="medium">
<Questions>What is Selenium ide Testing?</Questions>
<Tips>How to use selenium webdriver with eclipse ? </Tips>
<Multiple>Who was the ninth prime minister of India? </Multiple>
<Persons>Who is Spiderman? </Persons>
</Search>
<Search id="4444" type="optional">
<Questions>What is database Testing?</Questions>
<Tips>How to use Class in java ? </Tips>
<Multiple>Who was the eight prime minister of India? </Multiple>
<Persons>Who is motherindia? </Persons>
</Search>
</SearchStrings>
2) Creating a class which fetch nodes of tags at once and store all of them in
a String [] SearchString and then use this array to fetch the values and by .sendKeys(value) attribute search them at google.
Simplified:
1) Store elements tag element in an reusable datatype my knowledge is limited so using string array.
2) Fetch string array elements and search them using the .sendkeys(element) at google.
my code is as below:
package searchexperiment;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Experiment implements Paths
{
public static WebDriver driver;
static Document document;
static DocumentBuilder db;
public static void main(String args[])
{
String[] SearchStrings;
driver=new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
driver.get("https://www.google.com/");
//loading xml as test data
WebElement googlebox=driver.findElement(By.id("gbqfq"));
try {
FileInputStream file = new FileInputStream(new File(test_xml));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
System.out.println("*************************");
String expression="/SearchStrings/Search/Questions";
System.out.println("This is ordered expression \n"+expression);
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for(int i=0;i< nodeList.getLength();i++)
{
// Node nNode = emailNodeElementList.item(j);
// Element eElement = (Element) nNode;
System.out.println("Taking the loop value");
// below push is not working.
Object array = push(SearchStrings[i],nodeList.item(i).getFirstChild().getNodeValue());
String text=nodeList.item(i).getFirstChild().getNodeValue();
googlebox.clear();
googlebox.sendKeys(text);
System.out.println("Closing the loop value");
}
I am using the string array in order to make xml parsing class reusable.
I have used an interface to get file name
public interface Paths {
String test_xml="XML/Searchtext.xml";
}
Reusable method along with class was :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import searchexperiment.Paths;
public class DocBuilderClass implements Paths
{
public static String[] username()
{
String[] SearchElements=new String[4];
try
{
FileInputStream file = new FileInputStream(new File(test_xml));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
System.out.println("*************************");
String expression="/SearchStrings/Search/Tips";
System.out.println("This is ordered expression \n"+expression);
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
//int size=
for(int i=0;i< nodeList.getLength();i++)
{
// Node nNode = emailNodeElementList.item(j);
// Element eElement = (Element) nNode;
System.out.println("Taking the loop value");
//Object array = push(SearchStrings[i],nodeList.item(i).getFirstChild().getNodeValue());
String text=nodeList.item(i).getFirstChild().getNodeValue();
//googlebox.clear();
// googlebox.sendKeys(text);
SearchElements[i]=text;
System.out.println("Closing the loop value");
}
}
catch(Exception ex)
{
System.out.println("This is a exception" + ex);
}
finally
{
}
return SearchElements;
}
}
and then way to call the class was as follows:
String [] namelist=DocBuilderClass.username();
for(int i=0;i<namelist.length;i++)
{
String abc=namelist[i];
googlebox.sendKeys(abc);
googlebox.clear();
googlebox.sendKeys(namelist[i]);
}
References were Reference Link String[] array
Reference Link XML Parsing
All I learn that Your basics should be strong to solve a strong and complex problems.
I have been banging my head over for two days now.
I have a XHTML web-page from which i want to scrap some data
I am using JTidy to DOMParse and then XPathFactory to find nodes using XPath
The Xhtml snippet is something like this
<div style="line-height: 22px;" id="dvTitle" class="titlebtmbrdr01">BAJAJ AUTO LTD.</div>
Now i want that BAJAJ AUTO LTD.
The code that i am using is :
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class BSEQuotesExtractor implements valueExtractor {
#Override
public Vector<String> getName(Document d) throws XPathExpressionException {
// TODO Auto-generated method stub
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile("//div[#id='dvTitle']/text()");
Object result = expr.evaluate(d, XPathConstants.NODESET);
NodeList nodes = (NodeList)result;
for(int i=0;i<nodes.getLength();i++)
{
System.out.println(nodes.item(i).getNodeValue());
}
return null;
}
public static void main(String[] args) throws MalformedURLException, IOException, XPathExpressionException{
BSEQuotesExtractor q = new BSEQuotesExtractor();
DOMParser parser = new DOMParser(new URL("http://www.bseindia.com/bseplus/StockReach/StockQuote/Equity/BAJAJ%20AUTO%20LTD/BAJAJAUT/532977/Scrips").openStream());
Document d = parser.getDocument();
q.getName(d);
}
}
But i gett a null output and not BAJAJ AUTO LTD.
Please rescue me
try this.
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr = xpath.compile("//div[#id='dvTitle']");
Object result = expr.evaluate(d, XPathConstants.NODE);
Node node = (Node)result;
System.out.println(node.getTextContent());
you must use XPathConstants.STRING instead of XPathConstants.NODESET.
You want to get a value of a single element (div), not a list of nodes.
Write:
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
String divContent = (String) path.evaluate("//div[#id='dvTitle']", document, XPathConstants.STRING);
Into divContent you get "BAJAJ AUTO LTD.".
I am trying to use the namespace-uri() function in XPath to retrieve nodes based on their fully qualified name. The query //*[local-name() = 'customerName' and namespace-uri() = 'http://example.com/officeN'] in this online XPath tester, among others, correctly returns the relevant nodes. Yet the following self-contained Java class does not retrieve anything. What am I doing wrong with namespace-uri()?
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class Test{
public static void main(String[] args)throws Exception {
XPathExpression expr = XPathFactory.newInstance().newXPath().compile(
"//*[local-name() = 'customerName' and namespace-uri() = 'http://example.com/officeN']");
String xml=
"<Agents xmlns:n=\"http://example.com/officeN\">\n"+
"\t<n:Agent>\n\t\t<n:customerName>Joe Shmo</n:customerName>\n\t</n:Agent>\n"+
"\t<n:Agent>\n\t\t<n:customerName>Mary Brown</n:customerName>\n\t</n:Agent>\n</Agents>";
System.out.println(xml);
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
System.err.println("\n\nNodes:");
for (int i = 0; i < nodes.getLength(); i++) {
System.err.println(nodes.item(i));
}
}
}
The query looks fine. You also need to declare your DocumentBuilderFactory to be "namespace-aware".
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
My goal is executing an XQuery using XPath.
My XML file is:
<?xml version="1.0" encoding="UTF-8"?>
<postes>
<poste>
<gouvernourat>Kairouan</gouvernourat>
<ville>Kairouan sud</ville>
<cp>3100</cp>
</poste>
<poste>
<gouvernourat>Tunis</gouvernourat>
<ville>Ghazela</ville>
<cp>1002</cp>
</poste>
</postes>
My Java code is:
package xmlparse;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class QueryXML {
public void query() throws ParserConfigurationException, SAXException,
IOException, XPathExpressionException {
// Standard of reading a XML file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc = null;
XPathExpression expr = null;
builder = factory.newDocumentBuilder();
doc = builder.parse("a.xml"); //C:\\Users\\aymen\\Desktop\\
// Create a XPathFactory
XPathFactory xFactory = XPathFactory.newInstance();
// Create a XPath object
XPath xpath = xFactory.newXPath();
// Compile the XPath expression
expr = xpath.compile("/postes/poste[gouvernourat='Tunis']/ville/text()");
// Run the query and get a nodeset
Object result = expr.evaluate(doc, XPathConstants.NODESET);
// Cast the result to a DOM NodeList
NodeList nodes = (NodeList) result;
for (int i=0; i<nodes.getLength();i++){
System.out.println(nodes.item(i).getNodeValue());
}
}
public static void main(String[] args) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException {
QueryXML process = new QueryXML();
process.query();
}
}
When I launch this Java code the result is displayed on the console correctly (System.out.println).
But if I copy this code to my Android application and change System.out.println(nodes.item(i).getNodeValue()); to Text2.setText(nodes.item(i).getNodeValue()); (I have a TextView named Text2)
When I execute the code and I click the button the TextView stays empty (No error for Force Close)
Thank you in advance
Attribute names needs to start with '#' while using XPath in Android.
So change
[gouvernourat='Tunis']
To
[#gouvernourat='Tunis']
Refer http://developer.android.com/reference/javax/xml/xpath/package-summary.html for details.