I wouldlike to search in my xml file all attribut (name) without use element tag node :
xml :
<test 1><test1/>
<test2> <test2/>
<test 3 id="aaa"> </test3>
<test 5> </test5>
<test 6 id="bbb" name="ijof"> </test6>
JAVA :
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(path));
root = document.getDocumentElement();
String attribut = root.getAttribute("name");
System.out.println(attribut); // Expected ijof
Did you execute your code at least once? I dont't think so. Otherwise you would have surely noticed that your XML cannot be parsed.
There are several flaws in your example XML:
No root element.
Wrong end tags: It should be <test1></test1> and not <test1><test1/>.
Element names must not contain whitespace and start and end tag must match. It should be <test5> </test5> and not <test 5> </test5>
Apart of that you can use XPATH to get all elements with a name attribute.
Here is a complete example with the XML as a string but this should be irrelevant:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.StringReader;
public class FindNameAttribute {
private static final String XML =
"<root>\n" +
" <test1></test1>\n" +
" <test2> </test2>\n" +
" <test3 id=\"aaa\"> </test3>\n" +
" <test4 name=\"4\"/>\n" +
" <test5> </test5>\n" +
" <test6 id=\"bbb\" name=\"ijof\"> </test6>\n" +
" <test7 id=\"bbb\"><child name=\"childname\"/> </test7>\n" +
"</root>\n";
public static void main(String[] args) {
System.out.println(XML);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
StringReader reader = new StringReader(XML);
InputSource source = new InputSource(reader);
Document document = builder.parse(source);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//*[#name]", document, XPathConstants.NODESET);
for(int i = 0; i < nodes.getLength(); i++) {
Element el = (Element) nodes.item(i);
String elementName = el.getTagName();
String nameAttribute = el.getAttribute("name");
System.out.println(String.format("Element name: %s, name attribute: %s", elementName, nameAttribute));
}
} catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException e) {
e.printStackTrace();
}
}
}
This is the output:
<root>
<test1></test1>
<test2> </test2>
<test3 id="aaa"> </test3>
<test4 name="4"/>
<test5> </test5>
<test6 id="bbb" name="ijof"> </test6>
<test7 id="bbb"><child name="childname"/> </test7>
</root>
Element name: test4, name attribute: 4
Element name: test6, name attribute: ijof
Element name: child, name attribute: childname
The relevant XPATH expression is: //*[#name]
//: Looks for every element in the document
*: Placeholder for element name. Each name matches.
*[#name]: The [] denotes the predicate. We only want elements with a name attribute.
#: Means the following name is the name of an attribute. Whithout it would be interpreted as an element name
Related
I am trying to parse this xml file but I'm only getting the root elements and not it's child nodes.
I need information of some specific values from the nodes like using .item() method. Since, I'm not entering it's child nodes so it didn't give me the specified values. Please help me solving this...
XML file
<Ws>
<Id V='862631039910699'>
<Dt V='08/07/22;11/25'>
<T V='24.3;24.3;24.3'/>
<H V='98.0;98.0;98.0'/>
<W V='1.3;272'/>
<G V='25;2.4'/>
<A V='0.00;468;472;471'/>
<D V='0.00;8.9;8.065;0.0000;0.0000'/>
</Dt>
</Id>
</Ws>
package api;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
public class Web{
public static void main(String argv[])
{
try {
File file = new File("C:\\Users\\Prakhar\\OneDrive\\Desktop\\WBE2.xml.txt");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element: " + doc.getDocumentElement().getNodeName());
NodeList nodeList = doc.getElementsByTagName("Ws");
for (int i = 0; i < nodeList.getLength(); ++i) {
Node node = nodeList.item(i);
System.out.println("\nNode Name :" + node.getNodeName());
if (node.getNodeType()== Node.ELEMENT_NODE) {
Element tElement = (Element)node;
System.out.println("IMEI: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(0).getAttributes().getNamedItem("V").getNodeValue());
System.out.println("Date/Time: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(1).getAttributes().getNamedItem("V").getNodeValue());
System.out.println("Temperature: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(2).getAttributes().getNamedItem("V").getNodeValue());
System.out.println("Humidity: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(1).getAttributes().getNamedItem("V").getNodeValue());
System.out.println("Wind Speed: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(2).getAttributes().getNamedItem("V").getNodeValue());
}
}
}
catch (Exception e) {
System.out.println(e);
}
}
}
I need to loop through all chilnodes in the parent node (callEvents) and save each time the position of the child node.(First call event, second call event...). I'm stack in how to get the position of each child node in the parent node java/xpath?
say I have the following xml:
<callEvents>
<gprsCall>...</gprsCall>
<gprsCall>...</gprsCall>
<mobileOrigintaedCall>...</mobileOrigintaedCall>
<gprsCall>...</gprsCall>
<gprsCall>...</gprsCall>
</callEvents>
So the code should return:
My first gprsCall position = 1
My second gprsCall position = 2
My first mobileOriginatedCall position = 3
My third gprsCall position = 4
My fourth gprsCall position = 5
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathConstants;
import java.io.StringReader;
import org.xml.sax.InputSource;
class myxml {
static final String xml = "<callEvents>\n"
+ "<gprsCall>...</gprsCall>\n"
+ "<gprsCall>...</gprsCall>\n"
+ "<mobileOrigintaedCall>...</mobileOrigintaedCall>\n"
+ "<gprsCall>...</gprsCall>\n"
+ "<gprsCall>...</gprsCall>\n"
+ "</callEvents>";
public static void main (String... args) throws Throwable {
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
XPathExpression xpath = XPathFactory.newInstance().newXPath().compile("/callEvents/*");
NodeList nodelist = (NodeList) xpath.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodelist.getLength(); i++) {
System.out.println("Position: " + (i + 1)
+ ", name: " + nodelist.item(i).getNodeName());
}
} catch (Throwable e) {
throw e;
}
}
}
Iterate over the XPath callEvents/* and use the position() function to get the position.
This is an XSLT example:
<xsl:template match="/callEvents/*">
<xsl:value-of select="concat(local-name(),' - ',position() div 2)" />
</xsl:template>
I have XML data in data base (not file)
i need to parse it to gave possibility write test to verify data in xml
xml (content data):
<brid:AccountData xmlns:brid="http://billing.a1telekom.at/BridgeIT/BridgeITDefinition">
<brid:AccountNumber>250000000032</brid:AccountNumber>
<brid:CustomerNumber>100104653</brid:CustomerNumber>
<brid:AccountType>NORM</brid:AccountType>
<brid:BillCycle>M2</brid:BillCycle>
<brid:LastInvoiceDate>0001-01-01T00:00:00.000</brid:LastInvoiceDate>
<brid:BillThroughDate>0001-01-01T00:00:00.000</brid:BillThroughDate>
<brid:StartDate>2016-02-26T15:27:13</brid:StartDate>
<brid:EndDate>9999-12-31T23:59:59.000</brid:EndDate>
<brid:AccountStatus>Active</brid:AccountStatus>
<brid:TaxCode>U2</brid:TaxCode>
<brid:CostCentre></brid:CostCentre>
</brid:AccountData>
<brid:PaymentData xmlns:brid="http://billing.a1telekom.at/BridgeIT/BridgeITDefinition">
<brid:PaymentMethod>Manual</brid:PaymentMethod>
</brid:PaymentData>
<brid:MediaData xmlns:brid="http://billing.a1telekom.at/BridgeIT/BridgeITDefinition">
<brid:AccountNumber>250000000032</brid:AccountNumber>
<brid:MediaType>PAPIER</brid:MediaType>
<brid:StartDate>2016-02-26T15:27:13</brid:StartDate>
<brid:EndDate>9999-12-31T23:59:59.000</brid:EndDate>
<brid:InvoiceName>ApuiafgjkLrjgdna Fouydf</brid:InvoiceName>
<brid:Language>DE</brid:Language>
<brid:LocationID>118298</brid:LocationID>
<brid:FirstName>Fouydf</brid:FirstName>
<brid:LastName>ApuiafgjkLrjgdna</brid:LastName>
<brid:TitleCode></brid:TitleCode>
<brid:TitleText></brid:TitleText>
<brid:Prefix></brid:Prefix>
<brid:Suffix>Cxvb</brid:Suffix>
<brid:Currency>EUR</brid:Currency>
<brid:Format>2</brid:Format>
<brid:Atomized>N</brid:Atomized>
</brid:MediaData>
How i try to parse it:
p
ackage simbaOnlineReplacement;
import java.io.StringReader;
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;
import org.xml.sax.InputSource;
import ta.maxcare.help.DBSor;
public class XMLTest2 {
public static void main(String[] args) {
try {
String data = new DBSor().getContentData("106897066");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(data));
Document doc = dBuilder.parse(is);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("MediaData");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("First Name : " + eElement.getElementsByTagName("FirstName").item(0).getTextContent());
System.out.println("LastName : " + eElement.getElementsByTagName("LastName").item(0).getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
and e given error:
[Fatal Error] :14:2: The markup in the document following the root
element must be well-formed. org.xml.sax.SAXParseException;
lineNumber: 14; columnNumber: 2; The markup in the document following
the root element must be well-formed. at
com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown
Source) at
com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown
Source) at simbaOnlineReplacement.XMLTest2.main(XMLTest2.java:23)
In well formed XML, you must have one root element. brid:AccountData, brid:PaymentData and brid:MediaData are at the same level, and this is wrong. You should have a root element enclosing them all, as an example.
Your XML is a well-formed external general parsed entity, but it is not a well-formed document. The easiest way to handle it is therefore to create a simple wrapper file that references it as an external entity:
<!DOCTYPE wrapper [
<!ENTITY e SYSTEM "data.xml">
]>
<wrapper>&e;</wrapper>
and then parse the wrapper file.
I'm just starting out with learning how to process/parse XML data in Java. I'm getting the error, "The method getNodeType() is undefined for the type NodeList" on the line, after my for-loop, that contains:
if (n.getNodeType() == Node.ELEMENT_NODE){
The type of error seems like I forgot to import something, but I believe I got everything. I am using an XML example from microsoft, in the following link:
http://msdn.microsoft.com/en-us/library/ms762271(v=vs.85).aspx
Thanks in advance.
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
public class Files {
public static void main (String [] args) throws IOException, ParserConfigurationException{
String address = "/home/leo/workspace/Test/Files/src/file.xml";
File xmlFile = new File(address);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = factory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
System.out.println(doc.getDocumentElement().getNodeName());
NodeList n = doc.getElementsByTagName("book id");
for (int temp = 0; temp < n.getLength(); temp++){
System.out.println(n.item(temp));
if (n.getNodeType() == Node.ELEMENT_NODE){
Element e = (Element) n;
System.out.println("author : " + e.getAttribute("author"));
System.out.println("title : " + e.getAttribute("title") );
System.out.println("genre : " + e.getAttribute("genre"));
System.out.println("price : " + e.getAttribute("price"));
System.out.println("publish_date : " + e.getAttribute("publish_date"));
System.out.println("description : " + e.getAttribute("description"));
}
}
}
}
You are calling getNodeType() on a NodeList object (n).
You need to call this function on a Node object. Example :
n.item(temp).getNodeType();
I need a method like Document.getElementsByTagName(), but one that searches only tags from a certain level (ie, not nested tags with the same name)
Example file:
<script>
<something>
<findme></findme><!-- DO NOT FIND THIS TAG -->
</something>
<findme></findme><!-- FIND THIS TAG -->
</script>
Document.getElementsByTagName() simply returns all findme tags in the document.
Here is an example with XPath
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class TestXPath {
private static final String FILE = "a.xml" ;
private static final String XPATH = "/script/findme";
public static void main(String[] args) {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
docFactory.setNamespaceAware(true);
DocumentBuilder builder;
try {
builder = docFactory.newDocumentBuilder();
Document doc = builder.parse(FILE);
XPathExpression expr = XPathFactory.newInstance().newXPath().compile(XPATH);
Object hits = expr.evaluate(doc, XPathConstants.NODESET ) ;
if ( hits instanceof NodeList ) {
NodeList list = (NodeList) hits ;
for (int i = 0; i < list.getLength(); i++ ) {
System.out.println( list.item(i).getTextContent() );
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
With
<script>
<something>
<findme>1</findme><!-- DO NOT FIND THIS TAG -->
</something>
<findme>Find this</findme><!-- FIND THIS TAG -->
<findme>More of this</findme><!-- FIND THIS TAG AS WELL -->
</script>
It yields
Find this
More of this
If you're using DOM, the only way I can think of would be a recursive function that looks at the children of each element.
Use:
/*/findme
This XPath expression selects all findme elements that are children of the top element of the XML document.
This expression:
//findme[count(ancestor::*) = 5]
selects all findme elements in the XML document that have exactly five ancestor - elements -- that is, they all are at "level 6".