Reading List of Node using Xpath - java

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.

Related

How to parse a complex XML using Xpath

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

How to fetch node in XML using Java?

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

XPathFactory return xml document

I want to list some nodes from xml document by XPathFactory but I get plain text without xml nodes in return
My Xml Document is like this:
<?xml version="1.0" encoding="utf-8"?>
<journal>
<title>Hakim Research Journal</title>
<subject>Medical Sciences</subject>
<articleset>
<article>
<title>Challenges and Performance Improvement Approaches of Boards of Trustees of Universities of Medical Sciences and Health Services </title>
<content_type>Original</content_type>
</article>
<article>
<title> Risk Factors of Infant Mortality Rate in North East of Iran </title>
<content_type>Original</content_type>
</article>
</articleset>
</journal>
I want to have elements in return, like this:
<article>
<title>Challenges and Performance Improvement Approaches of Boards of Trustees of Universities of Medical Sciences and Health Services in Iran </title>
<content_type>Original</content_type>
</article>
<article>
<title> Risk Factors of Infant Mortality Rate in North East</title>
<content_type>Original</content_type>
</article>
My Code implementation is:
String result="";
File xmlDocument = new File("e://journal_last.xml");
InputSource inputSource = new InputSource(new FileInputStream(xmlDocument));
XPathFactory factory=XPathFactory.newInstance();
XPath xPath=factory.newXPath();
XPathExpression articleset;
articleset = xPath.compile("/journal/articleset/)");
result = articleset.evaluate(inputSource);
System.out.println(result);
but it just returns plain text of nodes without node tags !
The output is:
Challenges and Performance Improvement Approaches of Boards of Trustees of Universities of Medical Sciences and Health Services
Original
Risk Factors of Infant Mortality Rate in North East
Original
Would you please help me ?
I appreciate any help.
You can evaluate the XPath on a Document to get the NodeList of the articles and than write the NodeList as xml.
public class Main {
public static void main(String[] args) throws Exception {
File xmlDocument = new File("e://journal_last.xml");
FileInputStream xmlInputStream = new FileInputStream(xmlDocument);
Document doc = parseDocument(new InputSource(xmlInputStream));
NodeList articleList = evaluateXPath(doc, "/journal/articleset",
NodeList.class);
String xmlString = writeXmlString(articleList);
System.out.println(xmlString);
}
private static Document parseDocument(InputSource inputSource)
throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder = documentBuilderFactory
.newDocumentBuilder();
Document doc = docBuilder.parse(inputSource);
return doc;
}
#SuppressWarnings("unchecked")
private static <T> T evaluateXPath(Document doc, String xpath,
Class<T> resultType) throws XPathExpressionException {
QName returnType = resolveReturnType(resultType);
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
XPathExpression xpathExpression = xPath.compile(xpath);
Object resultObject = xpathExpression.evaluate(doc, returnType);
return (T) resultObject;
}
private static QName resolveReturnType(Class<?> clazz) {
if (NodeList.class.equals(clazz)) {
return XPathConstants.NODESET;
} else {
throw new UnsupportedOperationException("Not implemented yet");
}
}
private static String writeXmlString(NodeList nodeList)
throws TransformerConfigurationException,
TransformerFactoryConfigurationError, TransformerException {
StreamResult streamResult = new StreamResult(new StringWriter());
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
for (int i = 0; i < nodeList.getLength(); i++) {
Node articleListItem = nodeList.item(i);
DOMSource source = new DOMSource(articleListItem);
transformer.transform(source, streamResult);
}
String xmlString = streamResult.getWriter().toString();
return xmlString;
}
}

Get a specific child name in an XML file

I have an xml file like this:
<?xml version="1.0" encoding="UTF-8"?>
<ClOrdIDS><ClOrdID id="1"><Account>1005390</Account><Symbol>SAP</Symbol><SecurityID>4663789</SecurityID><SecurityExchange>XETR</SecurityExchange><Price>23.0</Price><Order_Type>Limit</Order_Type><Side>SELL</Side><Order_Quantity>0.001</Order_Quantity></ClOrdID><ClOrdID id="2"><Account>1005390</Account><Symbol>SAP</Symbol><SecurityID>4663789</SecurityID><SecurityExchange>XETR</SecurityExchange><Price>13.0</Price><Order_Type>Limit</Order_Type><Side>SELL</Side><Order_Quantity>0.001</Order_Quantity></ClOrdID><ClOrdID id="3"><Account>1005390</Account><Symbol>SAP</Symbol><SecurityID>4663789</SecurityID><SecurityExchange>XETR</SecurityExchange><Price>13.0</Price><Order_Type>Limit</Order_Type><Side>BUY</Side><Order_Quantity>0.001</Order_Quantity></ClOrdID><ClOrdID id="4"><Account>1005390</Account><Symbol>SAP</Symbol><SecurityID>4663789</SecurityID><SecurityExchange>XETR</SecurityExchange><Price>13.0</Price><Order_Type>Limit</Order_Type><Side>BUY</Side><Order_Quantity>0.001</Order_Quantity></ClOrdID><ClOrdID id="5"><Account>1005390</Account><Symbol>SAP</Symbol><SecurityID>4663789</SecurityID><SecurityExchange>XETR</SecurityExchange><Price>13.0</Price><Order_Type>Limit</Order_Type><Side>BUY</Side><Order_Quantity>0.001</Order_Quantity></ClOrdID><ClOrdID id="6"><Account>1005390</Account><Symbol>SAP</Symbol><SecurityID>4663789</SecurityID><SecurityExchange>XETR</SecurityExchange><Price>13.0</Price><Order_Type>Limit</Order_Type><Side>BUY</Side><Order_Quantity>0.001</Order_Quantity></ClOrdID><ClOrdID id="7"><Account>1005390</Account><Symbol>SAP</Symbol><SecurityID>4663789</SecurityID><SecurityExchange>XETR</SecurityExchange><Price>13.0</Price><Order_Type>Limit</Order_Type><Side>SELL</Side><Order_Quantity>0.001</Order_Quantity></ClOrdID></ClOrdIDS>
How can I extract the elements of child with ClOrdID id="3" ?
THANKS
You could do it this way
String xmlString = ...
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(xmlString);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
String xpathExp = "/ClOrdIDS/ClOrdID[#id=\"3\"]";
NodeList childNodeList = (NodeList) xpath.evaluate(xpathExp, doc, XPathConstants.NODESET);
Since the tags on the question are JDOM, not DOM, you could use JDOM instead ;-) :
Document doc = new SaxBuilder().build(xmlFile);
XPathExpression<Element> xpe = XPathFactory.instance()
.compile("/ClOrdIDS/ClOrdID[#id=\"3\"]", Filters.element());
List<Element> idThrees = xpe.evaluate(doc);
Here is the code to do it in VTD-XML...
import com.ximpleware.*;
public class removeElement {
public static void main(String s[]) throws VTDException{
VTDGen vg = new VTDGen();
if (!vg.parseFile("input.xml", false))
return;
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("/ClOrdIDS/ClOrdID[#id='3']");
int i=0;
while((i=ap.evalXPath())!=-1){
}
}
}

How to parse an xml and get the content of specific element

My xml String is
Got message from Queue ==> <?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003
/05/soap-envelope"><soapenv:Body><ns1:PostPublicationResponse xmlns:ns1="http://www.openoandm.org/xml/ISBM/"><ns1:Messag
eID>urn:uuid:7d361fb0-bc54-48bd-bbd1-6e34960ef3f8</ns1:MessageID><ns1:MessageContent><MessageContent xmlns="http://www.o
penoandm.org/xml/ISBM/"><hi>k786</hi></MessageContent></ns1:MessageContent></ns1:PostPublicationResponse></soapenv:Body>
</soapenv:Envelope>
Now i have writtent a function that is trying to get Content of element MessageContent i.e <hi>k786</hi> but i am getting null value always.
My function to parse above xml is:
private String parseQueueMessage(String message)
throws ParserConfigurationException, SAXException, IOException,
XPathExpressionException {
String resultMsg = "";
DocumentBuilderFactory domFactory = DocumentBuilderFactory
.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new java.io.StringReader(
message)));
XPath xpath = XPathFactory.newInstance().newXPath();
// XPath Query for showing all nodes value
xpath.setNamespaceContext(new NamespaceContext() {
#SuppressWarnings("rawtypes")
#Override
public Iterator getPrefixes(String arg0) {
return null;
}
#Override
public String getPrefix(String arg0) {
return null;
}
#Override
public String getNamespaceURI(String arg0) {
if("xmlns:ns1".equals(arg0)) {
return "http://www.openoandm.org/xml/ISBM/";
}
return null;
}
});
XPathExpression expr = xpath.compile("//xmlns:ns1:MessageContent");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("The message obtained after parsing : "
+ nodes.item(i).getNodeValue());
resultMsg = nodes.item(i).getNodeValue();
}
return resultMsg;
}
What i have done wrong in here?
Thanks in advance
You need to define the name space URI first before selecting from XPATH. For example, first define the namespace URI as follows on the root;
element.setAttribute("xmlns:ns1", "http://www.openoandm.org/xml/ISBM/");
xpath.compile("//ns1:MessageContent");
//Try something like ...
XmlDocument doc = new XmlDocument();
doc.LoadXml("urn:uuid:7d361fb0-bc54-48bd-bbd1-6e34960ef3f8k786
");
XmlElement elem = (XmlElement) doc.DocumentElement.FirstChild;
Console.Write("{0}:{1} = {2}", elem.Prefix, elem.LocalName, elem.InnerText);
Console.WriteLine("\t namespaceURI=" + elem.NamespaceURI);

Categories

Resources