I want to read XML data using XPath in java, so for the information I have gathered I am not able to parse xml according to my requirement,
I just want to take the value of bankId
this the example of the xml
I want to read XML data using XPath in java, so for the information I have gathered I am not able to parse xml according to my requirement,
I just want to take the value of 'bankId'
this part of the example of the xml
<?xml version="1.0" encoding="UTF-8"?>
<p:RawData xsi:type="p:RawData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ba="http://service.bni.co.id/bancslink" xmlns:bo="http://service.bni.co.id/core/bo" xmlns:core="http://service.bni.co.id/core" xmlns:mhp="http://service.bni.co.id/mhp" xmlns:mpnG2="http://service.bni.co.id/mhp/mpn_g2" xmlns:mpnG2_1="http://service.bni.co.id/bancslink/mpn_g2" xmlns:p="http://BP_MultiHostPayment">
<boList>
<name>McpRequest</name>
<bo xsi:type="bo:CommonBillPaymentReq">
<billerCode>0128</billerCode>
<regionCode>0001</regionCode>
<billerName>MPN G2 IDR</billerName>
<billingNum>820150629548121</billingNum>
<customerName>EVA RAJAGUKGUK SH. M.KN </customerName>
<paymentMethod>2</paymentMethod>
<accountNum>0373163437</accountNum>
<trxAmount>50000</trxAmount>
<naration>820150629548121</naration>
<invoiceNum>820150629548121</invoiceNum>
<billInvoiceNum1>INVNUM1</billInvoiceNum1>
<billAmount1>0</billAmount1>
<billInvoiceNum2>INVNUM2</billInvoiceNum2>
<billAmount2>0</billAmount2>
<billInvoiceNum3>INVNUM3</billInvoiceNum3>
<billAmount3>0</billAmount3>
<isDecAmount>false</isDecAmount>
<trxDecAmount>50000</trxDecAmount>
</bo>
</boList>
<boList>
<name>McpTellerHeader</name>
<bo xsi:type="core:TellerHeader">
<tellerId>00004</tellerId>
<branchCode>0997</branchCode>
<overrideFlag>I</overrideFlag>
</bo>
</boList>
<boList>
<name>HostRequest</name>
<bo xsi:type="mhp:Request">
<header>
<hostId>MPN_G2</hostId>
<channelId>ATM</channelId>
<branchId></branchId>
<terminalId></terminalId>
<locationId></locationId>
<transDateTime>2015-06-30T22:26:33</transDateTime>
<transId>20150630T222633N042462J0000001969R840SLEXI0</transId>
</header>
<content xsi:type="mpnG2:PaymentReq">
<bankId>520009000990</bankId>
<billingInfo1>013</billingInfo1>
<billingInfo2>03</billingInfo2>
<billingInfo3>409257</billingInfo3>
<branchCode>0997</branchCode>
<channelType>7010</channelType>
<currency>IDR</currency>
<gmt>2015-06-30T15:26:33.942</gmt>
<localDatetime>2015-06-30T22:26:33.943</localDatetime>
<settlementDate>0701</settlementDate>
<switcherCode>001</switcherCode>
<terminalId>S1HKWGA032</terminalId>
<terminalLocation>0997</terminalLocation>
<transactionId>013978</transactionId>
<amount>50000</amount>
<billerAccountNumber>3010194605</billerAccountNumber>
<customerName>EVA RAJAGUKGUK SH. M.KN </customerName>
<ntb>000000058111</ntb>
<paymentCode>820150629548121</paymentCode>
</content>
</bo>
</boList>
</p:RawData>
this is my java code
try {
FileInputStream file = new FileInputStream(new File("C:/Log/contoh.xml"));
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
System.out.println("hup hup");
String expression = "/p:RawData/boList/boList/boList/bo/content[#xsi:type='mpnG2:PaymentReq']/bankId";
System.out.println(expression);
String bankId = xPath.compile(expression).evaluate(xmlDocument);
System.out.println(bankId);
System.out.println("hup hup 2");
expression = "/p:RawData/boList/boList/boList/bo/content[#xsi:type='mpnG2:PaymentReq']/bankId";
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i=0; i < nodeList.getLength(); i++){
System.out.println(nodeList.item(i).getFirstChild().getNodeValue());
}
only this that appear when I run the code
hup hup
/p:RawData/boList/boList/boList/bo/content[#xsi:type='mpnG2:PaymentReq']/bankId
hup hup 2
any help will be pleasure :)
Try the following xpaths
//content[#xsi:type='mpnG2:PaymentReq']/bankId or
//content[#xsi:type='mpnG2:PaymentReq'][1]/bankId or
//bankId or
//bankId[1]
I've tested the xpaths for your xml in this online Xml Xpath tester
The XPath expression is wrong.
/p:RawData/boList/boList/boList/bo/content[#xsi:type='mpnG2:PaymentReq']/bankId
would select the element at:
<p:RawData>
<boList>
<boList>
<boList>
<bo>
<content xsi:type="mpnG2:PaymentReq" />
</bo>
</boList>
</boList>
</boList>
</RawData>
There is no such element in the XML.
You want
/p:RawData/boList[3]/bo/content[#xsi:type='mpnG2:PaymentReq']/bankId
To select the 3rd boList.
Related
I'm trying to read information from a specific element, here is my xml payload :
<?xml version="1.0"?>
<tns:createTicket xmlns:tns="">
<contact>
<gender>F</gender>
<firstname>ANNE</firstname>
<lastname>MP</lastname>
<phone>88</phone>
</contact>
<issue>
<occurrenceDate>2020-03-23T00:01:00+01:00</occurrenceDate>
<location>
<streetName1>Rpp</streetName1>
<zipCode>999999</zipCode>
<city>AMMM</city>
<countryCode>FR</countryCode>
</location>
<typeCode>GAM</typeCode>
<otherInformations>
<name>Ser</name>
<value>Two</value>
</otherInformations>
<otherInformations>
<name>deliveryAddress</name>
<value>RURU</value>
</otherInformations>
**<otherInformations>
<name>**serDat**</name>
<value>**2020-03-23**</value>
</otherInformations>**
<otherInformations>
<name>gracias</name>
<value>False</value>
</otherInformations>
</issue>
</tns:createTicket>
How can I read the informations from this specific element from the payload :
serDat
2020-03-23
I use the Dom librairy in my code but I'm only able to read the informations from the first 'otherinformations' element and not the other one. I don't have this problem when I want to read the informations from an unique element in the XML payload.
EDIT: I've tried the xPath Librairy
var factory = DocumentBuilderFactory.newInstance()
var builder = factory.newDocumentBuilder()
var document = builder.parse(new InputSource(new StringReader(payload)));
//var rootElement = document.getDocumentElement()
var xpf = XPathFactory.newInstance()
var xpath = xpf.newXPath()
print(payload)
var nodes = xpath.evaluate("/createTicketRequest/payload/issue/otherInformations", document, XPathConstants.NODESET) as NodeList
for(i in 0..nodes.getLength()) {
print(nodes.item(i).getNodeValue());
}
But the result of print(nodes.item(i).getNodeValue()); is NULL
Thank you for your help !
I am trying to merge two xml using
"javax.xml.xpath.XPath".
Both source and destination xml looks as below mentioned.
i want to append all the nodes of "bpmn:process" in the second xml to first xml
<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn">
<bpmn:collaboration id="Collaboration_1ah989h">
<bpmn:participant id="Participant_108if28" processRef="Process_2" />
</bpmn:collaboration>
<bpmn:process id="Process_1" isExecutable="false">**
<bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>SequenceFlow_1i0zw0x</bpmn:outgoing>
</bpmn:startEvent>
<bpmn:intermediateThrowEvent id="IntermediateThrowEvent_00epl00">
<bpmn:incoming>SequenceFlow_1i0zw0x</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_05qx4z2</bpmn:outgoing>
</bpmn:intermediateThrowEvent>
</bpmn:process>
</bpmn:definitions>
Below is the code used to merge xml
Document destination= (Document) xpath.evaluate("/", new InputSource("C:/diagram_Sec.bpmn"), XPathConstants.NODE);
NodeList listPosts = (NodeList) xpath.evaluate("//bpmn:process//*",new InputSource("C:/diagram_Fir.xml"), XPathConstants.NODESET);
Element element= (Element) xpath.evaluate("//bpmn:process", destination, XPathConstants.NODE);
for (int i = 0; i < listPosts.getLength(); i++) {
Node listPost = listPosts.item(i);
Element element = (Element) listPost;
AttributeMap map = (AttributeMap) element.getAttributes();
for(int j=0;j<map.getLength();j++)
{
element.setAttribute(map.item(j).getLocalName(), map.item(j).getNodeValue());
}
Node node = xml1.adoptNode(element);
blog.appendChild(node);
}
DOMImplementationLS impl = (DOMImplementationLS) xml1.getImplementation();
System.out.println(impl.createLSSerializer().writeToString(destination ));
The problem is, this code will consider all the child nodes of "bpmn:process" tag as seperate node and will put directly under "bpmn:process"(all the sub chidren will also come under "bpmn:process"). the output looks like this
<bpmn:process id="Process_1" isExecutable="false">
//Here comes First xml nodes
//Second XML Content after merge
<bpmn:startEvent id="StartEvent_1">
</bpmn:startEvent>
**//This tag should be inside bpmn:startEvent tag**
<bpmn:outgoing>SequenceFlow_1i0zw0x</bpmn:outgoing>
<bpmn:intermediateThrowEvent id="IntermediateThrowEvent_00epl00">
</bpmn:intermediateThrowEvent>
**//THis should be inside above bpmn:intermediateThrowEvent tag**
<bpmn:incoming>SequenceFlow_1i0zw0x</bpmn:incoming>
</bpmn:process
But the Expected is
<bpmn:process id="Process_1" isExecutable="false">
//Here comes First xml Children
//Second XML Content
<bpmn:startEvent id="StartEvent_1">
// outgoing is Inside bpmn:startEvent tag
**<bpmn:outgoing>SequenceFlow_1i0zw0x</bpmn:outgoing>**
</bpmn:startEvent>
<bpmn:intermediateThrowEvent id="IntermediateThrowEvent_00epl00">
// Inside bpmn:intermediateThrowEvent tag
<bpmn:incoming>SequenceFlow_1i0zw0x</bpmn:incoming>
</bpmn:intermediateThrowEvent>
</bpmn:process
Please let me know the correct way of doing this.
Thanks,
XPath is a read-only language: you can't use it to construct new XML trees. For that you need XSLT or XQuery. Or DOM, if you really want to sink that low.
But this is so easy in XSLT that using DOM really seems a waste of effort. In XSLT you just need two template rules: the standard identity rule to copy everything unchanged, plus the rule
<xsl:template match="bpmn:process">
<xsl:copy-of select="."/>
<xsl:copy-of select="document('second.xml')//bpmn:process"/>
</xsl:template>
I'm currently using XPath to get some information from a podcast feed using Java and XPath. I'm trying to read the attribute of a node:
<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:atom="http://www.w3.org/2005/Atom/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
<channel>
[....]
<itunes:image href="http://icebox.5by5.tv/images/broadcasts/14/cover.jpg" />
[...]
I want to get the value of the href attribute in <itunes:image>. Currently, I'm using the following code:
private static String IMAGE_XPATH = "//channel/itunes:image/#href";
String imageUrl = xpath.compile(IMAGE_XPATH).evaluate(doc, XPathConstants.STRING).toString();
The result of imageUrl is null. What happens in the code? Do I have an error in the XPath code, or in the Java code?
Thanks! :)
Disable namespace awarness:
DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
xmlFact.setNamespaceAware(false);
Your xpath expression should look like this now:
"//channel/image/#href"
If you need to use it as namespace aware, just implement your own NameSpaceContext, should look like this:
NamespaceContext ctx = new ItunesNamespaceContext();
XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath();
xpath.setNamespaceContext(ctx);
String IMAGE_XPATH = "//channel/itunes:image/#href";
String imageUrl = path.compile(IMAGE_XPATH).evaluate(doc,XPathConstants.STRING).toString();
EDIT: Here is a test code that proves my point:
String a ="<?xml version=\"1.0\" encoding=\"UTF-8\"?><rss xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:sy=\"http://purl.org/rss/1.0/modules/syndication/\" xmlns:admin=\"http://webns.net/mvcb/\" xmlns:atom=\"http://www.w3.org/2005/Atom/\" xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:content=\"http://purl.org/rss/1.0/modules/content/\" xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\" version=\"2.0\"><channel><itunes:image href=\"http://icebox.5by5.tv/images/broadcasts/14/cover.jpg\" /></channel></rss>";
DocumentBuilderFactory xmlFact = DocumentBuilderFactory.newInstance();
xmlFact.setNamespaceAware(false);
DocumentBuilder builder = xmlFact.newDocumentBuilder();
XPathFactory xpathFactory = XPathFactory.newInstance();
String expr = "//channel/image/#href";
XPath xpath = xpathFactory.newXPath();
Document doc = builder.parse(new InputSource(new StringReader(a)));
String imageUrl = (String) xpath.compile(expr).evaluate(doc ,XPathConstants.STRING);
System.out.println(imageUrl);
The output is:
http://icebox.5by5.tv/images/broadcasts/14/cover.jpg
The XPath should include the root element, so rss/channel/itunes:image/#href.
Alternatively, you could start the xpath with a // so that all levels are searched for the xpath (//channel/itunes:image/#href) but if the root will always be the same it is more efficient to use the first option.
I've got a section of XML that looks like this:
<entry>
<id>tag:example.com,2005:Release/343597</id>
<published>2012-04-10T11:29:19Z</published>
<updated>2012-04-10T12:04:41Z</updated>
<link type="text/html" href="http://example.com/projects/example1" rel="alternate"/>
<title>example1</title>
</entry>
I need to grab the link http://example.com/projects/example1 from this block. I'm not sure how to do this. To get the title of the project I use this code:
String title1 = children.item(9).getFirstChild().getNodeValue();
where children is the getChildNodes() object for the <entry> </entry> block. But I keep getting NullPointerExceptions when I try to get the node value for the <link> node in a similar way. I see that the XML code is different for the <link> node, and I'm not sure what it's value is.... Please advise!
The xpath expression to get that node is
//entry/link/#href
In java you can write
Document doc = ... // your XML document
XPathExpression xp = XPathFactory.newInstance().newXPath().compile("//entry/link/#href");
String href = xp.evaluate(doc);
Then if you need to get the link value of the entry with a specific id you can change the xpath expression to
//entry[id='tag:example.com,2005:Release/343597']/link/#href
Finally if you want to get all the links in the documents, if the document has many entry elements you can write
Document doc = ... // your XML document
XPathExpression xp = XPathFactory.newInstance().newXPath().compile("//entry/link/#href");
NodeList links = (NodeList) xp.evaluate(doc, XPathConstants.NODESET);
// and iterate on links
Here is the complete code:
DocumentBuilderFactory domFactory = DocumentBuilderFactory
.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("test.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("//entry/link/#href");
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));
}
Can somebody find what is wrong with this code. It always returns o nodes no matter whatever XPath I chose
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
domFactory.setIgnoringComments(true);
domFactory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document dDoc = builder.parse("P:/MyBooks.xml");
NodeList myNodes = (NodeList) xpath.evaluate("//Title", dDoc, XPathConstants.NODESET);
System.out.println(myNodes.getLength());
MyBookx.xml is:
<?xml version="1.0" encoding="UTF-8"?>
<Books>
<Title attrib="title1"/>
<Title attrib="title2"/>
<Title attrib="title3"/>
</Books>
I was doing a big mistake. My xml doc was using default namespace while I am setting NamespaceAware(true) in docFactory. So I set NamespaceAware(false) and my problem is solved