java - xpath - pom.xml
I am using following pom.xml file as xml dom resource, i want to get value of tag <version> without iterating in my code that's why i am using xpath but i guess my xpath express is not correct that's why it is not returning any value. any help appreciated.
java code
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("C:\\projects\\pom.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("project/version");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getNodeValue());
}
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dc.app</groupId>
<artifactId>rum</artifactId>
<packaging>war</packaging>
<version>12.54-SNAPSHOT</version>
<name>rum</name>
<description>rum</description>
</project>
Make a javax.xml.NamespaceContext and feed it to your xpath:
xpath.setNamespaceContext(ctx);
So:
DocumentBuilderFactory domFactory = DocumentBuilderFactory
.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("blah.pom");
XPath xpath = XPathFactory.newInstance().newXPath();
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("pom", "http://maven.apache.org/POM/4.0.0");
xpath.setNamespaceContext(
new NamespaceContextImpl("http://maven.apache.org/POM/4.0.0",
namespaces));
XPathExpression expr = xpath.compile("/pom:project/pom:version");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodes.item(i).getTextContent());
}
yields:
12.54-SNAPSHOT
EDIT: an implementation of the NamespaceContext:
public class NamespaceContextImpl implements NamespaceContext {
private final Map<String, String> namespaces;
private final String defaultNamespaceURI;
public NamespaceContextImpl(String defaultNamespaceURI,
Map<String, String> namespaces) {
this.defaultNamespaceURI = defaultNamespaceURI;
this.namespaces = namespaces;
}
public Iterator getPrefixes(String namespaceURI) {
throw new IllegalStateException("Not Implemented.");
}
public String getPrefix(String namespaceURI) {
throw new IllegalStateException("Not Implemented.");
}
public String getNamespaceURI(String prefix) {
if (prefix == null) {
throw new IllegalArgumentException();
}
if (prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
}
if (prefix.equals(XMLConstants.XML_NS_PREFIX)) {
return XMLConstants.XML_NS_URI;
}
if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
return defaultNamespaceURI;
}
String result = namespaces.get(prefix);
if (result == null) {
result = XMLConstants.NULL_NS_URI;
}
return result;
}
}
Related
I am trying to get the value of orderCode
public class ReadXml {
static Map<String, String> map = new HashMap<>();
static List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
public List<HashMap<String, String>> readxml() throws ParserConfigurationException, SAXException, IOException{
File file = new File(
"./resources/XMLFile/test.xml");
// Make an instance of the DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document dom = db.parse(file);
dom.getDocumentElement().normalize();
dom.getDocumentElement().getNodeName();
if (dom.hasChildNodes()) {
getNote(dom.getChildNodes()); // now re run
}
return list;
}
private static List<HashMap<String, String>> getNote(NodeList nodeList) {
Node node =null;
for (int count = 0; count < nodeList.getLength(); count++) {
HashMap<String, String> data = new HashMap<>();
Node tempNode = nodeList.item(count);
// make sure it's element node.
if (tempNode.getNodeType() == Node.ELEMENT_NODE) {
if (tempNode.hasAttributes()) {
//get attributes names and values
NamedNodeMap nodeMap = tempNode.getAttributes();
for (int i = 0; i < nodeMap.getLength(); i++) {
node = nodeMap.item(i);
node.getNodeName(); //
node.getNodeValue();
}
}
}
if (tempNode.hasChildNodes()) {
// loop again if has child nodes
getNote(tempNode.getChildNodes());
}
data.put(tempNode.getNodeName(), tempNode.getTextContent());
list.add(data);
}
return list;
}
}
Xml File is below:
<submit> <shortCode>NTT</shortCode>
<order orderCode="TEST/TEST192/2018SEP30/095552">
<description>RegressionTesting</description>
<amount currencyCode="abc"/>
debitCreditIndicator="test" exponent="2" value="123"/>
My problem is , it is not giving the value of OrderCode.
One word, xPath
So, fixing your XML to look like...
<submit>
<shortCode>NTT</shortCode>
<order orderCode="TEST/TEST192/2018SEP30/095552">
<description>RegressionTesting</description>
<amount currencyCode="abc"/>
</order>
</submit>
And using...
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse(new File("Sample.xml"));
XPathFactory xFactory = XPathFactory.newInstance();
XPath xPath = xFactory.newXPath();
XPathExpression exp = xPath.compile("/submit/order");
Node node = (Node) exp.evaluate(doc.getFirstChild(), XPathConstants.NODE);
if (node != null) {
Node value = node.getAttributes().getNamedItem("orderCode");
System.out.println(value.getTextContent());
}
} catch (Exception ex) {
ex.printStackTrace();
}
Which will print...
TEST/TEST192/2018SEP30/095552
or we can go straight to the attribute itself...
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document doc = factory.newDocumentBuilder().parse(new File("Sample.xml"));
XPathFactory xFactory = XPathFactory.newInstance();
XPath xPath = xFactory.newXPath();
XPathExpression exp = xPath.compile("/submit/order/#orderCode");
String value = (String) exp.evaluate(doc.getFirstChild(), XPathConstants.STRING);
System.out.println(value);
} catch (Exception ex) {
ex.printStackTrace();
}
Which will print...
TEST/TEST192/2018SEP30/095552
I would also consider having a look at Java API for XML Processing (JAXP) for more details
I want to get the File nodes of this xml document, can anyone help me with archive this issue?
I have this xml document:
<?xml version="1.0" encoding="UTF-8"?>
<Replies>
<FileList>
<File>cip13_test.rts</File>
<File>databar_lmt.rts</File>
<File>Test3.rts</File>
<File>databar2_lmt.rts</File>
<File>databar5_lmt.rts</File>
</FileList>
</Replies>
and I need to get all File-items from this.
I have this code but I get only cip13_test.rtx.
public static String GetFileList(String fileresponse) {
String xml = fileresponse;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
InputSource is = new InputSource();
String textToShow = "";
StringBuilder resultsofList = new StringBuilder();
try {
db = dbf.newDocumentBuilder();
is.setCharacterStream(new StringReader(xml));
try {
Document doc = db.parse(is);
NodeList replies = doc.getElementsByTagName("Replies");
for (int i = 0; i < replies.getLength(); i++) {
Element element = (Element) replies.item(i);
NodeList inkstatus = element.getElementsByTagName("FileList");
for (int i2 = 0; i2 < inkstatus.getLength(); i2++) {
Element element2 = (Element) inkstatus.item(i2);
NodeList inklevel = element2.getElementsByTagName("File");
for (int i4 = 0; i4 < inklevel.getLength(); i4++) {
Element element4 = (Element) inklevel.item(i4);
Element line = (Element) inklevel.item(0);
if (line == null) {
inklevel = element4.getElementsByTagName("File");
line = (Element) inklevel.item(0);
}
textToShow = getCharacterDataFromElement(line);
resultsofList.append(textToShow+",");
}
}
}
} catch (SAXException e) {
// handle SAXException
} catch (IOException e) {
// handle IOException
}
} catch (ParserConfigurationException e1) {
// handle ParserConfigurationException
}
return String.valueOf(resultsofList);
}
This line is wrong:
Element line = (Element) inklevel.item(0);
It should be
Element line = (Element) inklevel.item(i4);
I have an XML file and I need to delete a specific node. The node to be deleted will be defined dynamically based on the logic. I have been searching in internet for a solution but couldn't delete my node still. am getting error - NOT_FOUND_ERR: An attempt is made to reference a node in a context where it does not exist
Below is a sample XML File. I need to delete the node <NameValuePairs> which has <name>Local Variables</name>. Below is my sample XML Files Java Code
Sample XML File
<?xml version="1.0" encoding="UTF-8"?>
<DeploymentDescriptors xmlns="http://www.tibco.com/xmlns/dd">
<name>Test</name>
<version>1</version>
<DeploymentDescriptorFactory>
<name>RepoInstance</name>
</DeploymentDescriptorFactory>
<DeploymentDescriptorFactory>
<name>NameValuePairs</name>
</DeploymentDescriptorFactory>
<NameValuePairs>
<name>Global Variables</name>
<NameValuePair>
<name>Connections1</name>
<value>7222</value>
<requiresConfiguration>true</requiresConfiguration>
</NameValuePair>
<NameValuePair>
<name>Connections2</name>
<value>7222</value>
<requiresConfiguration>true</requiresConfiguration>
</NameValuePair>
</NameValuePairs>
<NameValuePairs>
<name>Local Variables</name>
<NameValuePair>
<name>Connections3</name>
<value>8222</value>
<requiresConfiguration>true</requiresConfiguration>
</NameValuePair>
<NameValuePair>
<name>Connections3</name>
<value>8222</value>
<requiresConfiguration>true</requiresConfiguration>
</NameValuePair>
</NameValuePairs>
</DeploymentDescriptors>
Java Code
File fDestFile = new File("myfile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document oDoc3 = dBuilder.parse(fDestFile);
NodeList oDestFlowList = oDoc3.getElementsByTagName("NameValuePairs");
for (int m = 0; m < oDestFlowList.getLength(); m++) {
NodeList oDestchildList = oDestFlowList.item(m).getChildNodes();
for (int n = 0; n < oDestchildList.getLength(); n++) {
Node oDestchildNode = oDestchildList.item(n);
if ("name".equals(oDestchildNode.getNodeName())) {
//oDestchildNode.getParentNode().removeChild(oDestchildNode); //Not Working
//oDoc3.getDocumentElement().removeChild(oDestchildNode); //Not Working
}
}
}
}
You need create a separate reference from the parent node as an Element so that you aren't referencing the node that you are removing:
File fDestFile = new File("src/myfile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = null;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document oDoc3 = null;
oDoc3 = dBuilder.parse(fDestFile);
NodeList oDestFlowList = oDoc3.getElementsByTagName("NameValuePairs");
// Loop through all 'NameValuePairs'
for (int m = oDestFlowList.getLength()-1; m >=0 ; m--) {
NodeList oDestchildList = oDestFlowList.item(m).getChildNodes();
// Loop through children of 'NameValuePairs'
for (int n = oDestchildList.getLength()-1; n >=0 ; n--) {
// Remove children if they are of the type 'name'
if(oDestchildList.item(n).getNodeName().equals("name")){
oDestFlowList.item(m).removeChild(oDestchildList.item(n));
// For debugging
System.out.println(oDestchildList.item(n).getNodeName());
}
}
}
Source source = new DOMSource(oDoc3);
Result result = new StreamResult(fDestFile);
Transformer transformer = null;
transformer = TransformerFactory.newInstance().newTransformer();
// Transform your XML document (i.e. save changes to file)
transformer.transform(source, result);
} catch (Exception e) {
// Catch the exception here
e.printStackTrace();
}
}
If you are still having issues, then I would think that it is an issue with the node types. This was working for me before I put the check in for 'oDestchildNode.getNodeType()' but I would look at what type of node you are returning and go from there.
Here is the final piece of code that finally worked
public static void main(String[] args) {
File fXmlSubFile = new File("Sub.xml");
File fXmlOriginalFile = new File("Original.xml");
File fDestFile = new File("myfile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
FileChannel source = null;
FileChannel destination = null;
XPath xPath = XPathFactory.newInstance().newXPath();
try{
if (!fDestFile.exists()) {
fDestFile.createNewFile();
}
source = new FileInputStream(fXmlOriginalFile).getChannel();
destination = new FileOutputStream(fDestFile).getChannel();
if (destination != null && source != null) {
destination.transferFrom(source, 0, source.size());
}
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
dBuilder = dbFactory.newDocumentBuilder();
Document oSubDoc = dBuilder.parse(fXmlSubFile);
Document oDestDoc = dBuilder.parse(fDestFile);
oSubDoc.getDocumentElement().normalize();
oDestDoc.getDocumentElement().normalize();
String sDestExpression = "/DeploymentDescriptors/NameValuePairs";
String sSubExpression = "/NameValuePairs";
NodeList nodeDestList = (NodeList) xPath.compile(sDestExpression).evaluate(oDestDoc, XPathConstants.NODESET);
NodeList nodeSubList = (NodeList) xPath.compile(sSubExpression).evaluate(oSubDoc, XPathConstants.NODESET);
for (int i = nodeDestList.getLength()-1; i >=0 ; i--) {
Node oDestNode = nodeDestList.item(i);
if (oDestNode.getNodeType() == Node.ELEMENT_NODE) {
Element oDestElement = (Element) oDestNode;
for (int j =0; j<nodeSubList.getLength(); j++) {
Node oSubNode = nodeSubList.item(j);
if (oSubNode.getNodeType() == Node.ELEMENT_NODE) {
Element oSubElement = (Element) oSubNode;
if(oDestElement.getElementsByTagName("name").item(0).getTextContent().equals(oSubElement.getElementsByTagName("name").item(0).getTextContent())){
oDestNode.getParentNode().removeChild(oDestNode);
}
}
}
}
}
Source src = new DOMSource(oDestDoc);
Result result = new StreamResult(fDestFile);
Transformer transformer = null;
transformer = TransformerFactory.newInstance().newTransformer();
// Transform your XML document (i.e. save changes to file)
transformer.transform(src, result);
}catch(Exception ex){
System.out.println("error:"+ex.getMessage());
ex.printStackTrace();
}
}
Hi I am trying to parse and XML file from an url, my NodeList contains values but getNodeValue for each node returns null. Can anybody help me?
This is my method where I parse the xml.
public ArrayList xmloku(String url) {
ArrayList xmllistesi = new ArrayList();
try {
URL xmlyolu = new URL(url);
DocumentBuilderFactory dFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
Document document = dBuilder.parse(new InputSource(xmlyolu
.openStream()));
document.getDocumentElement().normalize();
NodeList nodeListCountry = document
.getElementsByTagName("karikatur");
for (int i = konum; i < nodeListCountry.getLength(); i++) {
Node node = nodeListCountry.item(i);
Element elementMain = (Element) node;
xmllistesi.add(elementMain.getNodeValue());
}
Instead of getNodeValue() try using getTextContent()
for (int i = konum; i < nodeListCountry.getLength(); i++) {
Node node = nodeListCountry.item(i);
Element elementMain = (Element) node;
xmllistesi.add(elementMain.getTextContent());
}
I am trying to print out some data
so my code is
private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
private static final XPathFactory XPATH_FACTORY = XPathFactory.newInstance();
public void parseXml(String urlPath) throws Exception {
URL url = new URL(urlPath);
URLConnection connection = url.openConnection();
DocumentBuilder db = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
final Document document = db.parse(connection.getInputStream());
XPath xPathEvaluator = XPATH_FACTORY.newXPath();
XPathExpression nameExpr = xPathEvaluator.compile("lfm/results/trackmatches/track");
NodeList tracksinfoNodes = (NodeList) nameExpr.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < tracksinfoNodes.getLength(); i++) {
Node trackNameNode = tracksinfoNodes.item(i);
System.out.println(String.format("Track Name: %s" , trackNameNode.getTextContent()));
}
}
so it will print me like this for the first loop
Track Name:
I Believe in You
Neil Young
http://www.last.fm/music/Neil+Young/_/I+Believe+in+You
0
90540
http://userserve-ak.last.fm/serve/34s/65285990.png
http://userserve-ak.last.fm/serve/64s/65285990.png
http://userserve-ak.last.fm/serve/126/65285990.png
http://userserve-ak.last.fm/serve/300x300/65285990.png
the url I am using is http://ws.audioscrobbler.com/2.0/?method=track.search&track=Believe&api_key=b25b959554ed76058ac220b7b2e0a026
so what I am trying to do is to get eveyone alone , like this
song : I Believe in You
artist :Neil Young
link : http://www.last.fm/music/Neil+Young/_/I+Believe+in+You
something: 0
views: 90540
linkimg : http://userserve-ak.last.fm/serve/34s/65285990.png
..
..
Try something like this:
private static final DocumentBuilderFactory DOCUMENT_BUILDER_FACTORY = DocumentBuilderFactory.newInstance();
private static final XPathFactory XPATH_FACTORY = XPathFactory.newInstance();
public static void parseXml(String urlPath) throws Exception {
URL url = new URL(urlPath);
URLConnection connection = url.openConnection();
DocumentBuilder db = DOCUMENT_BUILDER_FACTORY.newDocumentBuilder();
final Document document = db.parse(connection.getInputStream());
XPath xPathEvaluator = XPATH_FACTORY.newXPath();
NodeList tracksinfoNodes = (NodeList) xPathEvaluator.compile("lfm/results/trackmatches/track").evaluate(
document, XPathConstants.NODESET);
for (int i = 0; i < tracksinfoNodes.getLength(); i++) {
Node trackNameNode = tracksinfoNodes.item(i);
NodeList childs = trackNameNode.getChildNodes();
for (int j = 0; j < childs.getLength(); j++) {
Node n = childs.item(j);
if (!n.getNodeName().equals("#text")) {
System.out.println(String.format("%s: %s", n.getNodeName(), n.getTextContent()));
}
}
System.out.println("==============");
}
}