blank lines when deleting nodes using JOOX and XPATH in Java - java

I'm using JOOX to process a xml file which I want to delete some nodes by a pattern.
This is a file example:
<?xml version="1.0" encoding="utf-8"?>
<results>
<result>
<location>5</location>
</result>
<result>
<location>19</location>
</result>
<result>
<location>23</location>
</result>
</results>
This is the Java code:
File file = new File("myfile.xml")
Document document = $(file).document();
$(document).xpath("//result[#location = id]").remove();
The deletion works ok but when I try to write the document to the file:
$(document).write(file);
All the deleted nodes produce blank lines in my xml file. I also realised that there is no xml header.
<?xml version="1.0" encoding="utf-8"?>
This is the produced file if I try to delete the location 5:
<results>
<result>
<location>19</location>
</result>
<result>
<location>23</location>
</result>
</results>
what am I doing wrong?

Related

Added redundant empty NameSpace while adding newly created element in somewhere middle of the xml document in java dom4j

I have xml template like this:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">
<body>
<content id="unique_id1">
</content>
<content id="unique_id2">
</content>
</body>
</root>
What I want to achieve is I want to insert new elements inside content tag by finding them by corresponding id.
Such as:
Element element = doc.selectSingleNode(//*[#id='unique_id2']");
Element newElement = DocumentHelper.createElement("new-element");
newElement.addText("new element text");
element.add(newElement);
This code can insert the newElement inside the specific element. But in newElement, a blank namespace is added automatically.
After insertion, the xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="..." xmlns:xsi="..." xsi:schemaLocation="...">
<body>
<content id="unique_id1">
</content>
<content id="unique_id2">
<new-element xmlns="">new element text</new-element>
</content>
</body>
</root>
So how to stop the empty namespace being added in the newElement?
You need to assign the correct namespace to the new Element; in this case the same namespace as the parent element:
Element newElement = DocumentHelper.createElement(QName.get("new-element", element.getNamespace()));

How to send request through SOAP UI with CDATA within CDATA to Java Application?

I am getting following exception while parsing XML
org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.
SOAp Request i am sending:
<soap:Envelope>
<soap:Header/>
<soap:Body>
<ver:ReceiveOnlineBatchExternalAttachment>
<web:username>user</web:username>
<web:passwd>pass</web:passwd>
<web:receiversReference>1232323</web:receiversReference>
<web:sequenceNumber>1</web:sequenceNumber>
<web:batch>
<![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<DataBatch>
<DataUnits>
<DataUnit>
<FormTask>
<ServiceCode>323015</ServiceCode>
<Form>
<FormData>
<![CDATA[<melding> </melding>]]
</FormData>
</Form>
</FormTask>
</DataUnit>
</DataUnits>
</DataBatch>
]]>>
</web:batch>
</ver:ReceiveOnlineBatchExternalAttachment>
</soap:Body>
</soap:Envelope>
I have done changes to CDATA multiple times but getting same error.
Could anyone suggest how CDATA within CDATA can be handled in this request?
Tried following but failed:
<![CDATA[ <elements> <![CDATA[<melding> </melding>]] <elements> ]]>>
<![CDATA[ <elements> <![CDATA[<melding> </melding>]]> <elements> ]]>
<![CDATA[ <elements> <![CDATA[<melding> </melding>]]> <elements> ]]>
I speculate that your problem is actually being caused by nested CDATA content. Can you try the following:
<![CDATA[
<DataBatch>
<DataUnits>
<DataUnit>
<FormTask>
<ServiceCode>323015</ServiceCode>
<Form>
<FormData>
<![CDATA[
<melding> </melding>
]]]]><![CDATA[>
</FormData>
</Form>
</FormTask>
</DataUnit>
</DataUnits>
</DataBatch>
]]>
The gist of the trick here is that when the parser hits the inner nested <![CDATA[ it will actually ignore it. Then, when it hits this:
]]]]><![CDATA[>
the first ]] will also be ignored, the following ]]> will be consumed, closing the outer CDATA, and then a new CDATA is immediately opened again which should last until the outer closing for that.
Edit by #fatherazrael:
Remove the XML tags <?xml version="1.0" encoding="UTF-8"?>
Reference: Nested CDATA - correctly

Creating xml using DOM in java

I am trying to create a an XML with multiple elements. Below is the code i am trying.
Element root = doc.createElement("root");
doc.appendChild(root);
Element member = doc.createElement("member");
root.appendChild(member);
Element name = doc.createElement("name");
name.appendChild(doc.createTextNode("xxx"));
member.appendChild(name);
Element phone = doc.createElement("phone");
phone.appendChild(doc.createTextNode("vvvv"));
member.appendChild(phone);
Element sss = doc.createElement("somethingNew");
root.appendChild(sss);
Element nnn = doc.createElement("name1");
nnn.appendChild(doc.createTextNode("AAA"));
sss.appendChild(nnn);
Element ppp = doc.createElement("phoneEx");
ppp.appendChild(doc.createTextNode("cc"));
sss.appendChild(ppp);
And the output i am getting is
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<member>
<name>xxx</name>
<phone>vvvv</phone>
<name>xxx</name>
<phone>vvvv</phone>
</member>
<somethingNew/>
</root>
But i am expecting somthing like Below, Please help me where i am going wriong
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<member>
<name>xxx</name>
<phone>vvvv</phone>
<name>xxx</name>
<phone>vvvv</phone>
</member>
<somethingNew>
<name1>DDD</name1>
<phoneEx>CC</phoneEx>
</somethingNew>
</root>
Never Mind i could able to find the solution, I am appending to the first element all the time, That was the issue.Corrected my code

Xml parsing and writing to another xml file in Java

How to parse xml file, so that it would write the same nodes to in another file several times, one after the other?
For example:
1.Xml file to be parsed:
<?xml version="1.0" encoding="UTF-8"?>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
2.As a result, I want to do so that was saved in another xml file, several times:
<?xml version="1.0" encoding="UTF-8"?>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
...
This is my previous question: Copy nodes in the same output xml file -java
The second example is not an XML file.
Add an external tag and appendChild to the root and save.
The file will remain valid then.
<?xml version="1.0" encoding="UTF-8"?>
<ALLs>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
</ALLs>
You may use random access files, jump to the end, position back before the write the new XML snippet and write again the ALLs. This should be fast.
Another option, which is useful with streams, to write the XML header always.
In this case you have to parse one-by-one, taking care that the InputStream what you pass for parsing does not close the inputStream (make your own subclass with a close that, indeed, does not close the file, and close externally; otherwise the XML parser will close the file).
<?xml version="1.0" encoding="UTF-8"?>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
<?xml version="1.0" encoding="UTF-8"?>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
Another option to use, e.g. JSON; convert your XML to JSON and append to a file; when reading, read line by line and convert the JSON to XML as you wish
Since your output doesn't contain a single root tag, it won't be valid XML. It sounds like you just want to output first line of file and then repeat subsequent lines an arbitrary number of times. If that's the case, you don't really care about fact that input file is [valid] XML. You could try something like the following:
final int cnt = 2;
Files.write(
Paths.get("out.txt"),
new AbstractList<String>() {
private final List<String> mStrs = Files.readAllLines(Paths.get("in.xml"));
public int size() {return 1 + (mStrs.size() - 1) * cnt;}
public String get(int pIdx) {
return
pIdx == 0 ?
mStrs.get(0) :
mStrs.get((pIdx - 1) % (mStrs.size() - 1) + 1);
}
}
);
Note that this solution assumes that input XML header is present.

Java XSL Transformation complaining about binding prefix to namespace

I try to transform a XML-document which is a TCX-file from a Garmin Watch with XSL and the javax.xml.transform.Transformer. This is the document (shorten):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2">
<Activities>
<Activity Sport="Running">
<Id>2014-08-23T15:36:15.000Z</Id>
<Lap StartTime="2014-08-23T11:50:34.000Z">
<TotalTimeSeconds>3181.0</TotalTimeSeconds>
<DistanceMeters>7620.0</DistanceMeters>
<MaximumSpeed>21.887998580932617</MaximumSpeed>
<Calories>386</Calories>
<AverageHeartRateBpm>
<Value>119</Value>
</AverageHeartRateBpm>
<MaximumHeartRateBpm>
<Value>167</Value>
</MaximumHeartRateBpm>
<Intensity>Active</Intensity>
<TriggerMethod>Manual</TriggerMethod>
<Track>
<Trackpoint>
<Time>2014-08-23T11:50:34.375Z</Time>
<Position>
<LatitudeDegrees>48.17259333333333</LatitudeDegrees>
<LongitudeDegrees>10.191565</LongitudeDegrees>
</Position>
<AltitudeMeters>542.5505981445312</AltitudeMeters>
<DistanceMeters>0.0</DistanceMeters>
<HeartRateBpm>
<Value>70</Value>
</HeartRateBpm>
<SensorState>Absent</SensorState>
</Trackpoint>
[...]
</Track>
<Notes>Note</Notes>
</Lap>
<Notes>Note</Notes>
<Training VirtualPartner="false">
<Plan Type="Workout" IntervalWorkout="false">
<Name>Running</Name>
<Extensions/>
</Plan>
</Training>
<Creator xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Device_t">
<Name>Polar V800</Name>
<UnitId>0</UnitId>
<ProductID>13</ProductID>
</Creator>
</Activity>
</Activities>
<Author xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Application_t">
<Name>no application</Name>
</Author>
</TrainingCenterDatabase>
I use the javax.xml.transform.Transformer for this task and get a strange error. The transformer gives me the following error message:
Element "xmlns:xsi" cannot have "xmlns" as its prefix.
It belongs to the line:
<Creator xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Device_t">
From my point of view, this line is valid. The given namespace is just bound to the prefix xsi. Is it necessary to configure the Transformer to detect it right or do I need to specify something in the xsl-file?
Thanks

Categories