I am here to ask you a basic question about jdom. I am trying to read a Document object but I got an error all the time.
The Document that I am trying to read is,
<message>
<header>
<messageType>snmp</messageType>
<sendFrom>192.168.0.16</sendFrom>
<hostName>oghmasysMehmet</hostName>
<sendTo>192.168.0.12</sendTo>
<receiverName>Mehmet</receiverName>
<date>03/10/2011</date>
</header>
<body>
<snmpType>getbulk</snmpType>
<ip>127.0.0.1</ip>
<port>161</port>
<oids>
<oid>1.3.6.1.2.1.1</oid>
</oids>
<community>public</community>
<nR>0</nR>
<mR>5</mR>
</body>
</message>
And I am trying to value. To do it, I have written a function,
public Vector<String> getOIDs(Document document){
Vector<String> oids = new Vector<String>();
Element root = document.getRootElement();
Element body = root.getChild("body");
//Element element = body.getChild("oids");
List rows = body.getChildren("oid");
for (int i = 0; i < rows.size(); i++) {
Element row = (Element) rows.get(i);
String s = row.getText();
oids.add(s);
}
return oids;
}
but When I debug it, I can always see that there is nothing read by the function.
Can you please help me about that ?
Thank you all
EDIT :Ok sorry for asking such a noob question, I just made a mistake in getchildren (); I should have written oids instead of oid
EDIT 2: Actually ı have changed the code as I commented on my question but now, the only thing I read is "\n \n" not "1.3.6.1.2.1.1". What do you think the problem might be ?
At first glance, seems to me that doesn't have a "oid" child, it has a "oids" child. The element you're trying to read is inside the "oids" element.
You can try and debug it step by step, and see what is the element that isn't being read. That would be my best guess without trying it out.
Your commented out line was correct, the line below it just needs to be updated to match. Your listing should be:
Vector<String> oids = new Vector<String>();
Element root = document.getRootElement();
Element body = root.getChild("body");
Element element = body.getChild("oids");
List rows = element.getChildren("oid");
for (int i = 0; i < rows.size(); i++) {
Element row = (Element) rows.get(i);
String s = row.getText();
oids.add(s);
}
return oids;
Related
Essentially, i'm creating an XML document from a file (a database), and then i'm comparing another parsed XML file (with updated information) to the original database, then writing the new information into the database.
I'm using java's org.w3c.dom.
After lots of struggling, i decided to just create a new Document object and will write from there from the oldDocument and newDocument ones i'm comparing the elements in.
The XML doc is in the following format:
<Log>
<File name="something.c">
<Warning file="something.c" line="101" column="23"/>
<Warning file="something.c" line="505" column="71" />
</File>
</Log>
as an example.
How would i go about adding in a new "warning" Element to the "File" without getting the pesky "org.w3c.dom.DOMException: WRONG_DOCUMENT_ERR: A node is used in a different document than the one that created it." exception?
Cutting it down, I have something similar to:
public static Document update(Element databaseRoot, Element newRoot){
Document doc = db.newDocument(); // DocumentBuilder defined previously
Element baseRoot = doc.createElement("Log");
//for each file i have:
Element newFileRoot = doc.createElement("File");
//some for loop that parses through each 'file' and looks at the warnings
//when i come to a new warning to add to the Document:
NodeList newWarnings = newFileToCompare.getChildNodes(); //newFileToCompare comes from the newRoot element
for (int m = 0; m < newWarnings.getLength(); m++){
if(newWarnings.item(m).getNodeType() == Node.ELEMENT_NODE){
Element newWarning = (Element)newWarnings.item(m);
Element newWarningRoot = (Element)newWarning.cloneNode(false);
newFileRoot.appendChild(doc.importNode(newWarningRoot,true)); // this is what crashes
}
}
// for new files i have this which works:
newFileRoot = (Element)newFiles.item(i).cloneNode(true);
baseRoot.appendChild(doc.importNode(newFileRoot,true));
doc.appendChild(baseRoot);
return doc;
}
Any ideas? I'm beating my head against the wall. First time doing this.
Going through with a debugger I verified that the document owners were correct. Using node.getOwnerDocument(), I realized that the newFileRoot was connected to the wrong document earlier when I created it, so I changed
Element newFileRoot = (Element)pastFileToFind.cloneNode(false);
to
Element newFileRoot = (Element)doc.importNode(pastFileToFind.cloneNode(false),true);
since later on when i was trying to add the newWarningRoot to newFileRoot, they had different Documents (newWarningRoot was correct but newFileRoot was connected to the wrong document)
I am really unsure how I can get the information I need to place into a database, the code below just prints the whole file.
File input = new File("shipMove.txt");
Document doc = Jsoup.parse(input, null);
System.out.println(doc.toString());
My HTML is here from line 61 and I am needing to get the items under the column headings but also grab the MMSI number which is not under a column heading but in the href tag. I haven't used JSoup other than to get the HTML from the web page. I can only really see tutorials to use php and I'd rather not use it.
To get those information, the best way is to use Jsoup's selector API. Using selectors, your code will look something like this (pseudeocode!):
File input = new File("shipMove.txt");
Document doc = Jsoup.parse(input, null);
Elements matches = doc.select("<your selector here>");
for( Element element : matches )
{
// do something with found elements
}
There's a good documentation available here: Use selector-syntax to find elements. If you get stuck nevertheless, please describe your problem.
Here are some hints for that selector, you can use:
// Select the table with class 'shipinfo'
Elements tables = doc.select("table.shipinfo");
// Iterate over all tables found (since it's only one, you can use first() instead
for( Element element : tables )
{
// Select all 'td' tags of that table
Elements tdTags = element.select("td");
// Iterate over all 'td' tags found
for( Element td : tdTags )
{
// Print it's text if not empty
final String text = td.text();
if( text.isEmpty() == false )
{
System.out.println(td.text());
}
}
}
I have two seperate java Document objects:
Doc1 :
<CIS_REQUEST>
<Request1>
</CIS_REQUEST>
<CIS_RESPONSE>
<RESPONSE1>
<RESPONSE2>
</CIS_RESPONSE>
Doc2 :
<CIS_REQUEST>
<Request1>
</CIS_REQUEST>
I want the resulting document to look like:
<CIS_REQUEST>
<Request1>
</CIS_REQUEST>
<CIS_RESPONSE>
<RESPONSE1>
<RESPONSE2>
</CIS_RESPONSE>
<PROCESSING>1</PROCESSING>
<CIS_PROFILES>
<CIS_REQUEST>
<Request1>
</CIS_REQUEST>
<CIS_PROFILES>
The code I have so far:
Document doc2 = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(combinedResponse);
counter++;
String counter_str = Integer.toString(counter);
Element count = doc2.createElement("PROCESSING");
root.appendChild(count);
Text counter_text = doc2.createTextNode(counter_str);
count.appendChild(counter_text);
Element profileElement = doc2.createElement(profName + "_profiles");
profileElement.append(doc1) //I need some replacement for this code.
Can anyone educate me on how I can just append one document to another, and not insert it somewhere in the original document?
I am new to read XML in Java using DOM. Could someone help me with simple code steps to read this XML in DOM?
Here is my XML:
<DataSet xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='datamartschema.1.3.xsd'>
<DataStream title='QUESTIONNAIRE'>
<Record>
<TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>xhaksdj</SubType>
<IntegerValue title='ComponentID'>11111</IntegerValue>
</Record><Record>
<TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>jhgjhg</SubType>
<IntegerValue title='ComponentID'>11111</IntegerValue>
</Record>
</DataStream>
</DataSet>
In this XML I need to read the DataStream value and Record values. My expected output is
DataStream=QUESTIONNAIRE and my records are
<TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>xhaksdj</SubType><IntegerValue title='ComponentID'>11111</IntegerValue><TransactionDate>2014-05-28T14:17:31.2186777-06:00</TransactionDate><SubType>jhgjhg</SubType><IntegerValue title='ComponentID'>11111</IntegerValue>
How can I get this output? I tried myself but I can't get the records output like above. I get the output without Tags which are present in the above output.I am using this line to get the output. But it does not give me correct output. Also, how to read the datastream value from this XML? Kindly help me.
This is my code snippets
NodeList datasetallRecords = indElement.getElementsByTagName("Record");
for (int y = 0; y < datasetallRecords.getLength(); y++) {
Element recordsElement = (Element) datasetallRecords.item(y);
recordXMl = recordXMl + recordsElement.getTextContent();
String d = datasetallRecords.item(y).getTextContent();
if (recordsElement.getTagName().equalsIgnoreCase("SubType")) {
lsDataStreamSubTypes.add(recordsElement.getTextContent());
}
recordCount = y;
}
When you create new instance of builder you can get DataStream
it would be look like this:
Element root = document.getDocumentElement();
NodeList dataStreams = root.getElementsByTagName("DataStream");
then get throw this list and get all info like this:
for (int i = 0; i < dataStreams.lenght(); i++) {
Element dataStream = (Element) dataStreams.item(i);
if (dataStream.getNodeType() == Element.ELEMENT_NODE) {
String title = dataStream.getAttributes()
.getNamedItem("title").getTextContent();
}
}
First you need to create a Node like this
Node nNode = datasetallRecords.item(y);
then an element like this
Element eElement = (Element) nNode;
now you can start taking the values from the element by using the getelementbyid and getnodevalue method.
You're not getting the tags because the call to getTextContent() on the "Record" node will return only the textual content of that node and its descendants.
If you need to nodes as well you'll have to process the XML by hand. Have a look at the DOM tutorial it covers processing a document in DOM mode very well including how to read out element names.
I would like to insert a node in an xml file using Java DOM. I am actually editing a lot of contents of a dummy file in order to mofidy it like the original.
I would want to add an open node and close node in between the following file;
<?xml version="1.0" encoding="utf-8"?>
<Memory xmlns:xyz="http://www.w3.org/2001/XMLSchema-instance"
xmlns:abc="http://www.w3.org/2001/XMLSchema" Derivative="ABC"
xmlns="http://..">
///////////<Address> ///////////(which I would like to insert)
<Block ---------
--------
-------
/>
////////// </Address> /////////(which I would like to insert)
<Parameters Thread ="yyyy" />
</Memory>
I hereby request you to let me know how to I insert -- in between the xml file?
Thanks in advance.!
What I have tried doing is;
Element child = doc.createElement("Address");
child.appendChild(doc.createTextNode("Block"));
root.appendChild(child);
But this gives me an output like;
<Address> Block </Address> and not the way i expect :(
And now, what I have tried is to add these lines;
Element cd = doc.createElement("Address");
Node Block = root.getFirstChild().getNextSibling();
cd.appendChild(Block);
root.insertBefore(cd, root.getFirstChild());
But still, this is not the output which i am looking for. I got this output as
---------
What you want is probably:
Node parent = block.getParentNode()
Node blockRemoved = parent.removeChild(block);
// Create address
parent.appendChild(address);
address.appendChild(blockRemoved);
This is the standard way to re-attach a node in another place under W3C DOM.
Here:
DocumentBuilder b = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = b.parse(...);
// Parent of existing Block elements and new Address elemet
// Might be retrieved differently depending on
// actual structure
Element parent = document.getDocumentElement();
Element address = document.createElement("address");
NodeList nl = parent.getElementsByTagName("Block");
for (int i = 0; i < nl.getLength(); ++i) {
Element block = (Element) nl.item(i);
if (i == 0)
parent.insertBefore(address, block);
parent.removeChild(block);
address.appendChild(block);
}
// UPDATE: how to pretty print
LSSerializer serializer =
((DOMImplementationLS)document.getImplementation()).createLSSerializer();
serializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
LSOutput output =
((DOMImplementationLS)document.getImplementation()).createLSOutput();
output.setByteStream(System.out);
serializer.write(document, output);
I assume you are using the W3C DOM (e.g. http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html ). If so try
insertBefore(address, block);