I have an XML as below :
<Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="someurl" xsi:schemaLocation="someurl Sample.xsd">
<RequestControl>
<requestID>100129</requestID>
<Control>
<requesterName>Admin</requesterName>
<requesterLanguage>100</requesterLanguage>
</Control>
</RequestControl>
<Inquiry>
<InquiryType>getParty</InquiryType>
<InquiryParam>
<Param name="PartyId">854850029276139020</Param>
</InquiryParam>
</Inquiry>
</Service>
I want to extract the value "getParty" from tag using XPath XML Parser. I am using the below as my expression :
expression = xPath.compile("/Service/Inquiry/InquiryType/text()");
How can I write the accurate and complete java code for the above? I just want to extract the value for <InquiryType>getParty</InquiryType>.
Trying your code, it looks like it is working fine for me. Here is what I did
public static void main(String ... args) throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(System.getProperty("user.dir") + "/src/main/resources/test.xml");
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expression = xpath.compile("/Service/Inquiry/InquiryType/text()");
NodeList xpathNodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);
System.out.println("InquiryType is : " +xpathNodeList.item(0));
}
With test.xml containing exactly the xml you are using
<Service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="someurl" xsi:schemaLocation="someurl Sample.xsd">
<RequestControl>
<requestID>100129</requestID>
<Control>
<requesterName>Admin</requesterName>
<requesterLanguage>100</requesterLanguage>
</Control>
</RequestControl>
<Inquiry>
<InquiryType>getParty</InquiryType>
<InquiryParam>
<Param name="PartyId">854850029276139020</Param>
</InquiryParam>
</Inquiry>
</Service>
I am using the below method :
public static String inputXmlXPathParser(String inputXml){
//==================================================X-Path Parser =============================================================//
String transactionName = StringUtils.EMPTY;
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new InputSource( new StringReader(inputXml)));
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expression = xpath.compile("/Service/Inquiry/InquiryType/text()");
NodeList xpathNodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);
System.out.println("InquiryType is : " +xpathNodeList.item(0));
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (XPathExpressionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return transactionName;
}
Related
I have a use case where my XML is like this
<IR>
<name>abc</name>
<Level></Level>
</IR>
<IR>
<name>xyz</name>
<Level>LVL00006</Level>
</IR>
I am using below code to extract information of level.
public class TestUseCases {
public static void main(String[] args) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
} catch (ParserConfigurationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Document document;
try {
document = factory.newDocumentBuilder()
.parse(new InputSource(new StringReader(xml)));
String xpathExpression = "";
Map<String, List<String>> iRValues = new LinkedHashMap<String, List<String>>();
xpathExpression = "(/IR/Level/text())";
iRValues.put("REQLVL", evaluateXPath(document, xpathExpression));
System.out.println(iRValues);
} catch (SupportException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException | IOException | ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static List<String> evaluateXPath(Document document, String xpathExpression) throws SupportException {
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
List<String> values = new ArrayList<>();
try {
// Create XPathExpression object
XPathExpression expr = xpath.compile(xpathExpression);
// Evaluate expression result on XML document
NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
System.out.println(nodes.getLength());
for (int i = 0; i < nodes.getLength(); i++) {
String item = nodes.item(i).getNodeValue();
System.out.println(item);
if (item.trim().isEmpty()) {
values.add(SupportConstants.EMPTY_SPACE);
} else {
values.add(nodes.item(i).getNodeValue());
}
}
} catch (XPathExpressionException e) {
throw new SupportException(SupportExceptionMessage.ERROR_IN_READING_RESPONSE_FROM_CM);
}
return values;
}
}
OUTPUT:
1
LVL00006
{REQLVL=[LVL00006]}
The problem is because first level tag is empty, I get a list which has only one element and I am not able to know whether the element is of abc or xyz. Is there a way so that I can put space if the tag is empty?
I am expecting list as [" ", LVL00006].
try {
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc = builder.parse("15122021.xml");
NodeList currencyList= doc.getElementsByTagName("Currency");
for(int i=0;i<currencyList.getLength();i++){
Node p = currencyList.item(i);
if(p.getNodeType()==Node.ELEMENT_NODE){
Element mainTag = (Element) p;
NodeList currencySellPriceList= mainTag.getElementsByTagName("ForexSelling");
NodeList currencyBuyPriceList = mainTag.getElementsByTagName("ForexBuying");
NodeList currencyNameList2= mainTag.getElementsByTagName("CurrencyName");
for(int j=0;j<currencyNameList2.getLength();j++){
Node c=currencyNameList2.item(j);
Node cbp=currencyBuyPriceList.item(j);
Node csp=currencySellPriceList.item(j);
if(c.getNodeType()==Node.ELEMENT_NODE && cbp.getNodeType()==Node.ELEMENT_NODE && csp.getNodeType()==Node.ELEMENT_NODE){
System.out.println("Currency name: "+c.getTextContent());
System.out.println("Buy price: "+cbp.getTextContent());
System.out.println("Sell price: "+csp.getTextContent());
}
}
}
}
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (SAXException e) {
System.out.println(e.getMessage());
}
I am trying to parse XML file like this in main method and it works.But when i try to take this code block to another method like this
public class XMLScraperBuilder {
public NodeList getBuyPrices() throws IOException, SAXException, ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
NodeList currencySellPriceList=null;
DocumentBuilder builder=factory.newDocumentBuilder();
Document doc = builder.parse("15122021.xml");
NodeList currencyList= doc.getElementsByTagName("Currency");
for(int i=0;i<currencyList.getLength();i++){
Node currency = currencyList.item(i);
if(currency.getNodeType()==Node.ELEMENT_NODE){
Element mainTag = (Element) currency;
currencySellPriceList= mainTag.getElementsByTagName("ForexSelling");
for(int j=0;j<currencySellPriceList.getLength();j++){
Node c = currencySellPriceList.item(j);
}
}}
return currencySellPriceList;
}}
It returns nothing when i try to print the NodeList with a for loop in my main method(after creating an object from XMLScraperBuilder).Any ideas?
I want to fetch value of the node ServerVersion
<result>
<response id="27mSTG">
<routing>
<configs>
<linqmap.routing.RoutingServerConfig>
<SERVER_VERSION>1.0.388</SERVER_VERSION>
<PRE_PROCESSING_FILE_LOCATION/>
I have tried:
#Override
public void getProp(String prop) {
try {
final Document document = loadXMLFromString();
document.getElementById(??);
} catch (Exception e) {
e.printStackTrace();
}
}
private Document loadXMLFromString() throws Exception
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xmlString));
return builder.parse(is);
}
But I’m not sure how to get the node’s ID.
Is there any easier way? Maybe even string parsing is enough?
There is no attribute Id defined in your xml element SERVER_VERSION. You can use document.getElementByTagName("SERVER_VERSION") to get the value.
Or use XPath to read the node:
final Document document = loadXMLFromString();
XPathFactory xpathfactory = XPathFactory.newInstance();
XPath xpath = xpathfactory.newXPath();
String xpathExpr="/result/SERVER_VERSION"; // assume result is the root node.
Node node=(Node)xPath.compile(xpathExpr).evaluate(document, XPathConstants.NODE);
I am trying to read from xml file but I get a null pointer exception.
this is the xml file:
<war>
<missileLaunchers>
<launcher id="L101" isHidden="false">
<missile id="M1" destination="Sderot" launchTime="2" flyTime="12" damage="1500"/>
<missile id="M2" destination="Beer-Sheva" launchTime="5" flyTime="7" damage="2000"/>
</launcher>
<launcher id="L102" isHidden="true">
<missile id="M3" destination="Ofakim" launchTime="4" flyTime="3" damage="5000"/>
<missile id="M4" destination="Beer-Sheva" launchTime="9" flyTime="7" damage="1000"/>
</launcher>
</missileLaunchers>
<missileDestructors >
<destructor id="D201">
<destructdMissile id="M1" destructAfterLaunch="4"/>
<destructdMissile id="M3" destructAfterLaunch="7" />
<destructdMissile id="M4" destructAfterLaunch="2"/>
</destructor>
<destructor id="D202">
<destructdMissile id="M2" destructAfterLaunch="3"/>
</destructor>
</missileDestructors>
<missileLauncherDestructors >
<destructor type="plane" >
<destructedLanucher id="L101" destructTime="4"/>
</destructor>
<destructor type="ship">
<destructedLanucher id="L102" destructTime="8" />
<destructedLanucher id="L102" destructTime="12"/>
</destructor>
</missileLauncherDestructors>
</war>
and this is the code:
public class XmlReader
{
File fXmlFile=null;
DocumentBuilderFactory dbFactory=null;
DocumentBuilder dBuilder=null;
Document doc=null;
public XmlReader(String filePath) throws ClassNotFoundException
{
if(filePath!=null)
{
this.fXmlFile = new File(filePath);
dbFactory = DocumentBuilderFactory.newInstance();
try {
dBuilder = dbFactory.newDocumentBuilder();
} catch (ParserConfigurationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
} catch (SAXException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else System.out.println("Xml file not found");
}
//gets value by tag name
private static String getTagValue(String tag, Element element) {
if(element.hasChildNodes())
{
NodeList nodeList = element.getElementsByTagName(tag).item(0).getChildNodes();
Node node = (Node) nodeList.item(0);
if(node==null)
return null;
return node.getNodeValue();
}
else return element.getNodeValue();
}
//launcher
public List<Launcher> readLauncher() throws Exception
{
List<Launcher> launcherList = new ArrayList<Launcher>();
try
{
NodeList nList = doc.getElementsByTagName("launcher");
for(int i=0;i<nList.getLength();i++)
{launcherList.add(getLauncher(nList.item(i)));}
}
catch (Exception e)
{
e.printStackTrace();
}
return launcherList;
}
//builds the object
private static Launcher getLauncher(Node node)
{
//XMLReaderDOM domReader = new XMLReaderDOM();
Launcher launcher = new Launcher();
if (node.getNodeType() == Node.ELEMENT_NODE)
{
Element element = (Element) node;
// launcher.setIsHidden(Boolean.parseBoolean(getTagValue("isHidden", element)));
// launcher.setId(getTagValue("id", element));
System.out.println("id = "+getTagValue("id", element));
System.out.println("ishidden = "+getTagValue("isHidden", element));
}
return launcher;
}
}
And this is the stack trace:
java.lang.NullPointerException
at XmlReader.getTagValue(XmlReader.java:56)
at XmlReader.getLauncher(XmlReader.java:96)
at XmlReader.readLauncher(XmlReader.java:78)
at Program.main(Program.java:27)
I can not change the format of the xml file.
It seems to fail when it tries to get the actual value of the node's fields or so I assume.
Though I don;t understand the reason...when I check the size of the node list it turns fine it does give me 2.
The problem is below line:
System.out.println("id = " + getTagValue("id", element));
where getTagValue("id", element) is calling
NodeList nodeList = element.getElementsByTagName(tag).item(0).getChildNodes();
Here element.getElementsByTagName("id") will return null
It should be get from attribute
// gets value by tag name
private static String getTagValue(String tag, Element element) {
return element.getAttributeNode(tag).getValue();
}
You are calling getElementsByTagName() in getTagValues, however you are trying to retrieve attributes of the tag. You may need to call getAttribute() instead. For Example:
element.getAttribute(attributeName)
where attributeName is "id" or "isHidden". This will return the value as a String and can be returned directly with no further processing.
this is my XML file :
<sitemesh>
<mapping path="/editor/tempPage/**" exclude="true"/>
<mapping decorator="/WEB-INF/views/decorators/detailstheme.jsp"
path="/*" exclude="false" />
</sitemesh>
I want list of mapping node with their attribute values.
this should be done using Xpath.
my xpath expression is :
expr = xpath.compile("/sitemesh/mapping");
but i am getting null in nodelist.
this is my code:
Map<String,String> map=new HashMap<String, String>();
// reading xml file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
Document doc = null;
XPathExpression expr = null;
try {
builder = factory.newDocumentBuilder();
// creating input stream
doc = builder.parse(file);
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
expr = xpath.compile("//mapping");
} catch (Exception e) {
LOG.error("some exception message", e);
}
//------------------------------------------------------------------------
NodeList attributeElements = null;
try {
attributeElements =(NodeList)expr.evaluate(doc, XPathConstants.NODE);
} catch (XPathExpressionException e) {
LOG.error("some exception message", e);
}
System.out.println("lenght:"+attributeElements.getLength());
for (int i = 0; i < attributeElements.getLength(); i++) {
Node node=attributeElements.item(i);
System.out.println("node:"+node.getNodeValue());
NamedNodeMap attrs = node.getAttributes();
for(i = 0 ; i<attrs.getLength() ; i++) {
Attr attribute = (Attr)attrs.item(i);
System.out.println("Node Attributes : " + attribute.getName()+" = "+attribute.getValue());
}
}
//-------------------------------------------------------------------------
// writing xml file
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer;
try {
transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(file);// creating output
// stream
transformer.transform(source, result);
} catch (Exception e) {
LOG.error("some exception message", e);
}
return map;
i am getting null for attributeElements
i want to show values of path,decorator and exclude on JSP page.But i am unable to get list of node through xpath expression.
I want solution for reading mapping node element in Xpath.
[edit] /sitemesh/mapping also works .
The issue here is that you evaluating the express for XPathConstants.NODE while the nodeList maps to XPathConstants.NODESET. please refer below link.
http://docs.oracle.com/javase/1.5.0/docs/api/javax/xml/xpath/XPathConstants.html#NODESET
Added sample code for illustration purpose only:
public void testXpathExpr(){
String testXML = "<sitemesh><mapping path=\"/editor/tempPage/**\" exclude=\"true\"/><mapping decorator=\"/WEB-INF/views/decorators/detailstheme.jsp\" path=\"/*\" exclude=\"false\" /></sitemesh>";
NodeList nodeList = getNodeList(testXML);
}
private NodeList getNodeList(String xml) throws SAXException, IOException, ParserConfigurationException, XPathExpressionException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = docFactory.newDocumentBuilder();
document = builder.parse(new ByteArrayInputStream( xml.getBytes() ) );
XPathExpression exprPath = xpath.compile(xpathExpr);
NodeList nodeList = (NodeList) exprPath.evaluate(document, XPathConstants.NODESET);;
return nodeList;
}
Hope this helps!
Your xpath works perfectly for me. Below is the sample code:
public class Parser {
public static void main(String[] args) throws Exception, Exception {
final DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
final DocumentBuilder builder = factory.newDocumentBuilder();
final Document doc = builder.parse("src/sitemesh.xml");
final XPathFactory xPathfactory = XPathFactory.newInstance();
final XPath xpath = xPathfactory.newXPath();
final XPathExpression expr = xpath.compile("/sitemesh/mapping");
Object node = expr.evaluate(doc, XPathConstants.NODE);
System.out.println(node);
}
}
sitemesh.xml contains your sample input.