I have an XML like the following,
<?xml version="1.0" encoding="utf-8"?>
<PaymentElement>
<Payment seqID="3">
<TPayment>
<Status>status</Status>
</TPayment>
</Payment>
</PaymentElement>
The question is how do I retrieve/extract seqID value which is 3 out of this via java.
I have tried the following way, but it doesn't work.
InputStream xml = conn.getInputStream();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xml);
NodeList list = doc.getElementsByTagName("PaymentElement");
for(int i=0; i<=list.getLength();i++){
NodeList paySeq=doc.getElementsByTagName("Payment seqID");
System.out.println("Payment seqID"+paySeq);
}
try
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new File("1.xml"));
Element e = (Element)doc.getDocumentElement().getElementsByTagName("Payment").item(0);
String id = e.getAttribute("seqID");
System.out.println("Payment seqID = " + id);
output
Payment seqID = 3
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("/PaymentElement/Payment/#seqID");
Object result = expr.evaluate(doc, XPathConstants.STRING);
result should be having 3 now.
Full Example
import java.io.*;
import javax.xml.xpath.*;
import org.xml.sax.InputSource;
public class Demo {
public static void main(String[] args) throws Exception {
InputStream inputStream = new FileInputStream("sample.xml");
InputSource inputSource = new InputSource(inputStream);
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("/PaymentElement/Payment/#seqID");
Object result = expr.evaluate(inputSource, XPathConstants.STRING);
System.out.println(result);
}
}
Related
I need to read a small xml file and validate it's content against a hardcoded HashMap with key= tag and value= text inside tag.
I can not get the tag name of the Node.
If I convert the Node to Element I get a cast exception.
I am reading using the DOOM classes:
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
NodeList list = doc.getElementsByTagName("MergeOptions");
if (list.getLength() == 0)
{
//throw
}
NodeList config = list.item(0).getChildNodes();
for (int i = 0; i <= config.getLength() - 1; i++)
{
Node setting = config.item(i);
String nodeName = setting.getNodeValue();
String value = setting.getTextContent();
if (defaultMergeOptions.containsKey(nodeName) == false)
{
//throw
}
if (defaultMergeOptions.get(nodeName).equals(value))
{
//throw
}
Xml file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MergeOptions>
<sometagName>false</sometagName>
</MergeOptions>
I am helping you with the following code structure. Once you see the tag name and the value, you can apply the logic to compare from HashMap key or value.
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class Test1 {
public static void main(String[] args) throws Exception {
String xmlFile = "test.xml";
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
Element root = doc.getDocumentElement();
System.out.println(root.getNodeName());
NodeList list = root.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
System.out.println(node.getNodeName() + " : " + node.getTextContent());
}
}
}
}
I have tried to run your code, it works fine, no class cast exceptions.
Note how I used the element in the for loop the get the name, value or the existsnce of a possible children.
final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<MergeOptions>\n<sometagName>false</sometagName>\n</MergeOptions>";
final InputStream xsmlStream = new ByteArrayInputStream(xml.getBytes());
final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
final DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
final Document doc = dBuilder.parse(xsmlStream);
final NodeList nodes = doc.getElementsByTagName("MergeOptions");
for (int i = 0; i < nodes.getLength(); i++) {
final Element element = (Element) nodes.item(i);
System.out.println(element.hasChildNodes());
System.out.println(element.getNodeValue());
System.out.println(element.getTagName());
}
Using hash map is with node names as keys is a bit tricky, 'cause if your XML file have multiple node names with same names and different values, the HashMap will only store only one unique keys thus validate only one of the same name nodes. The other same name nodes but with different values will be not valid.
Well I did something diffrent.
Seems to work:
IntegrationTest.getInstance().getLogger().log(Level.INFO, "Reading merge-que file: " + xmlFile.getAbsolutePath());
try
{
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
for (Entry<String, String> entry : defaultMergeOptions.entrySet())
{
String tagName = entry.getKey();
NodeList list = doc.getElementsByTagName(tagName);
if (list.getLength() != 1)
{
IntegrationTest.getInstance().getLogger().log(Level.SEVERE, TestResult.FAIL, "Merge option [{0}] has invalid content. Tag [{1}] missing or to many",
new Object[] { xmlFile.getName(), tagName });
result = TestResult.FAIL;
continue;
}
if (!defaultMergeOptions.get(tagName).equals(list.item(0).getTextContent()))
{
IntegrationTest.getInstance().getLogger().log(Level.WARNING, TestResult.FAIL, "Merge option [{0}] has diffrent content for tag [{1}].",
new Object[] { xmlFile.getCanonicalPath(), tagName });
result = TestResult.FAIL;
}
}
}
catch (Exception e)
{
IntegrationTest.getInstance().getLogger().log(Level.SEVERE, SBUtil.stackTraceToString(e.getStackTrace()));
throw new IntegrationTestException(e);
}
}
I have the following XML (provided by a web service)
<?xml version="1.0" encoding="UTF-8"?>
<itam>
<status>OK</status>
<data>
<item0>
<id>246</id>
<prefisso_quadrato>1</prefisso_quadrato>
<id_incontro_corrente />
<id_giornata>65</id_giornata>
<round>R1</round>
<tempo>120</tempo>
<punti_chong>0</punti_chong>
<punti_hong>0</punti_hong>
<amm_chong>0</amm_chong>
<amm_hong>0</amm_hong>
</item0>
<item1>
<id>247</id>
<prefisso_quadrato>2</prefisso_quadrato>
<id_incontro_corrente />
<id_giornata>65</id_giornata>
<round>R1</round>
<tempo>120</tempo>
<punti_chong>0</punti_chong>
<punti_hong>0</punti_hong>
<amm_chong>0</amm_chong>
<amm_hong>0</amm_hong>
</item1>
<item2>
<id>248</id>
<prefisso_quadrato>3</prefisso_quadrato>
<id_incontro_corrente />
<id_giornata>65</id_giornata>
<round>R1</round>
<tempo>120</tempo>
<punti_chong>0</punti_chong>
<punti_hong>0</punti_hong>
<amm_chong>0</amm_chong>
<amm_hong>0</amm_hong>
</item2>
</data>
</itam>
I am trying to parse it in JAVA. I can access to the <status> and also to the <data> element. But when I try to iterate over <data> items, I can read just 1 element. This is the code:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
Document doc = builder.parse(is);
doc.getDocumentElement().normalize();
System.out.println(doc.getDocumentElement().getElementsByTagName("data").getLength());
OUTPUT: 1
My idea was something like the code below, but it runs just over the first element (I can read the rest element attributes and then it ends). How can I fix it? Thank you very much
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
Document doc = builder.parse(is);
doc.getDocumentElement().normalize();
NodeList nodelist = doc.getDocumentElement().getElementsByTagName("data");
if(nodelist!=null){
for(int i=0; i<nodelist.getLength(); i++){
Element el = (Element) nodelist.item(i);
//use el to get data from it
}
}
The error is that you are looking for a list of <data> element and you have just one. A solution can be:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
Document doc = builder.parse(is);
doc.getDocumentElement().normalize();
NodeList items = doc.getDocumentElement().getElementsByTagName("data").item(0).getChildNodes();
for(int i=0; i<items.getLength(); i++){
System.out.println(items.item(i).getNodeName());
}
Good luck!
You will have to recurively iterate over the xml file to get all the elements..
something like this
private Document getDocument(String xsdUrl)
throws ParserConfigurationException, SAXException, IOException {
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
final DocumentBuilder db = dbf.newDocumentBuilder();
final Document doc = db.parse(xsdUrl);
return doc;
}
private void processElementRecurse(final Element node) throws IOException,
ParserConfigurationException, SAXException, TransformerException {
final NodeList nl = node.getChildNodes();
for (int i = 0, n = nl.getLength(); i < n; i++) {
final Node childNode = nl.item(i);
if (childNode instanceof Element) {
}
else {
processElementRecurse(childElement);
}
}
}
How should i get the Link value from the below xml
XML Content
<document-instance system="abc.org" number-of-pages="6" desc="Drawing" link="www.google.com">
<document-format-options>
<document-format>application/pdf</document-format>
<document-format>application/tiff</document-format>
</document-format-options>
<document-section name="DRAWINGS" start-page="1" />
</document-instance>
i traverse update desc attribute after that i'm struggle
XPathExpression firstPageUrl = xPath.compile("//document-instance/#desc=\"Drawing\"]");
Expected output : retrieve the Link value
www.google.com
File file = new File("path to file");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//document-instance/#link";
Node node = (Node) xPath.compile(expression).evaluate(doc, XPathConstants.NODE);
String url= node.getTextContent();
<?xml version="1.0" encoding="UTF-8"?>
<filepaths>
<application_information_ticker>
<desc>Ticker1</desc>
<folder_path>../atlas/info/</folder_path>
</application_information_ticker>
<document_management_system>
<desc></desc>
<folder_path>../atlas/dms/</folder_path>
</document_management_system>
</filepaths>
I have a xml file like this. I need to convert this xml file into java object using JAXB. Because of nested tags, I couldn't perform the operation. Please suggest me a solution for this
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource( new StringReader( xmlString) );
Document doc = builder.parse( is );
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
xpath.setNamespaceContext(new PersonalNamespaceContext());
XPathExpression expr = xpath.compile("//src_small/text()");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
List<String> list = new ArrayList<String>();
for (int i = 0; i < nodes.getLength(); i++) {
list.add (nodes.item(i).getNodeValue());
System.out.println(nodes.item(i).getNodeValue());
My xml file looks like this
<InNetworkCostSharing>
<FamilyAnnualDeductibleAmount>
<Amount>6000</Amount>
</FamilyAnnualDeductibleAmount>
<IndividualAnnualDeductibleAmount>
<NotApplicable>Not Applicable</NotApplicable>
</IndividualAnnualDeductibleAmount>
<PCPCopayAmount>
<CoveredAmount>0</CoveredAmount>
</PCPCopayAmount>
<CoinsuranceRate>
<CoveredPercent>0</CoveredPercent>
</CoinsuranceRate>
<FamilyAnnualOOPLimitAmount>
<Amount>6000</Amount>
</FamilyAnnualOOPLimitAmount>
<IndividualAnnualOOPLimitAmount>
<NotApplicable>Not Applicable</NotApplicable>
</IndividualAnnualOOPLimitAmount>
</InNetworkCostSharing>
I am trying to get Amount value from <FamilyAnnualDeductibleAmount> and also from <FamilyAnnualOOPLimitAmount>. How do i get those values in java?
You may use two XPath queries /InNetworkCostSharing/FamilyAnnualDeductibleAmount and InNetworkCostSharing/FamilyAnnualOOPLimitAmount or just get the node InNetworkCostSharing and retrieve the values of its two direct children.
Solution using XPath:
// load the XML as String into a DOM Document object
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
ByteArrayInputStream bis = new ByteArrayInputStream("YOUR XML".getBytes());
Document doc = docBuilder.parse(bis);
// XPath to retrieve the content of the <FamilyAnnualDeductibleAmount> tag
XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("/InNetworkCostSharing/FamilyAnnualDeductibleAmount/text()");
String familyAnnualDeductibleAmount = (String)expr.evaluate(doc, XPathConstants.STRING);
StAX based solution:
XMLInputFactory f = XMLInputFactory.newInstance();
XMLStreamReader rdr = f.createXMLStreamReader(new FileReader("test.xml"));
while (rdr.hasNext()) {
if (rdr.next() == XMLStreamConstants.START_ELEMENT) {
if (rdr.getLocalName().equals("FamilyAnnualDeductibleAmount")) {
rdr.nextTag();
int familyAnnualDeductibleAmount = Integer.parseInt(rdr.getElementText());
System.out.println("familyAnnualDeductibleAmount = " + familyAnnualDeductibleAmount);
} else if (rdr.getLocalName().equals("FamilyAnnualOOPLimitAmount")) {
rdr.nextTag();
int familyAnnualOOPLimitAmount = Integer.parseInt(rdr.getElementText());
System.out.println("FamilyAnnualOOPLimitAmount = " + familyAnnualOOPLimitAmount);
}
}
}
rdr.close();
Note that StAX is especially good for cases like yours, it skips all unnecessary elements reading only the ones you need
Try something like this(use getElementsByTagName to get the parent nodes and then get the value be reaching out to child node):
File xmlFile = new File("NetworkCost.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile );
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("FamilyAnnualDeductibleAmount");
String familyDedAmount = nList.item(0).getChildNodes().item(0).getTextContent();
nList = doc.getElementsByTagName("FamilyAnnualOOPLimitAmount");
String familyAnnualAmount =
nList.item(0).getChildNodes().item(0).getTextContent();
I think I found the solution with this question from stackoverflow
Getting XML Node text value with Java DOM