i try to parse text from xml file and then write it and save in docx file with apachepoi XWPFDocument, it creates docx file, but it's empty, i cant seen there my text from parsed xml. Any suggestions will be appreciated?
xml:
`<document>
<el id="1">
<text>Rakesh</text>
</el>
<el id="2">
<text>John</text>
</el>
<el id="3">
<text>Rajesh</text>
</el>
</document>`
code:
public void dothis() throws ParserConfigurationException, SAXException,
IOException, TransformerFactoryConfigurationError,
TransformerException {
in = new BufferedReader(new FileReader("D:\\Probe.xml"));
XWPFDocument document1 = new XWPFDocument();
XWPFParagraph paragraphOne = document1.createParagraph();
XWPFRun paragraphOneRunOne = paragraphOne.createRun();
paragraphOneRunOne.setText(in);
PrintWriter zzz = new PrintWriter(new FileWriter("D:\\dd3.docx"));
document1.write(zzz);
zzz.close();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// Get the DOM Builder
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("D:\\Probe.xml");
List<Elementt> empList = new ArrayList<>();
// Iteration durch den Knoten und die kinder Knoten extraktion
NodeList nodeList = document.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if (node instanceof Element) {
Elementt emp = new Elementt();
emp.id = node.getAttributes().getNamedItem("id").getNodeValue();
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node cNode = childNodes.item(j);
// Unterelementen von xml identifizieren
if (cNode instanceof Element) {
String content = cNode.getLastChild().getTextContent()
.trim();
switch (cNode.getNodeName()) {
case "text":
emp.text = content;
break;
}
}
}
empList.add(emp);
}
Based on my experience with XWPFRun when you do this:
paragraphOneRunOne.setText(in);
The 'in' needs to equal the text you want to input. Your 'in' is equal to the following:
in = new BufferedReader(new FileReader("D:\\Probe.xml"));
Try parsing the text first, then setting that as your character run, something like:
String in = textFromXMLFile
paragraphOneRunOne.setText(in);
Or, if I have understood your code correctly (I haven't done any xml yet), and the ArrayList contains your text, something like:
List<Elementt> empList = new ArrayList<>();
for(int i = 0; i < empList.length(); i++){
paragraphOneRunOne.setText(empList.get(i));
}
The main point is whenever you set the runtext, whatever you use at that point seems to be what is inputted, so you need the relevant data ready before setting the run with it.
Good luck!
Related
I need to get value like "Symbol" ect. from xml file and send to list.
For now my code looks like this:
Scanner sc = null;
byte[] buff = new byte[1 << 13];
List<String> question2 = new ArrayList<String>();
question2 = <MetodToGetFile>(sc,fileListQ);
for ( String strLista : question2){
ByteArrayInputStream in = new ByteArrayInputStream(strLista.getBytes());
try(InputStream reader = Base64.getMimeDecoder().wrap(in)){
try (GZIPInputStream gis = new GZIPInputStream(reader)) {
try (ByteArrayOutputStream out = new ByteArrayOutputStream()){
int readGis = 0;
while ((readGis = gis.read(buff)) > 0)
out.write(buff, 0, readGis);
byte[] buffer = out.toByteArray();
String s2 = new String(buffer);
}
}
}
}
}
I want to know how can i contunue this and takevalue "xxx" and "zzzz" to put to another list, because i need to compere some value.
XML looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Name Name="some value">
<Group Names="some value">
<Package Guid="{7777-7777-7777-7777-7777}">
<Attribute Typ="" Name="Symbol">xxx</Attribute>
<Attribute Type="" Name="Surname">xxx</Attribute>
<Attribute Type="Address" Name="Name">zzzz</Attribute>
<Attribute Type="Address" Name="Country">zzzz</Attribute>
</Package>
EDIT: Hello i hope that my solution will be usefull for someone :)
try{
//Get is(inputSource with xml in s2(xml string value from stream)
InputSource is = new InputSource(new StringReader(s2));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(is);
XPathFactory xpf = XPathFactory.newInstance();
XPath xpath = xpf.newXPath();
//Get "some value" from attribut Name
String name= (String) xpath.evaluate("/Name/#Name", doc, XPathConstants.STRING);
//Get "guid" from attribute guid
String guid= (String) xpath.evaluate("/Name/Group/Package/#Guid", doc, XPathConstants.STRING);
//Get element xxx by tag value Symbol
String symbol= xpath.evaluate("/Name/Group/Package/Attribute[#Name=\"Symbol\"]", doc.getDocumentElement());
System.out.println(name);
System.out.println(guid);
System.out.println(symbol);
}catch(Exception e){
e.printStackTrace();
}
I would be happy if i will help someone by my code :)
Add a method like this to retrieve all of the elements that match a given Path expression:
public List<Node> getNodes(Node sourceNode, String xpathExpresion) throws XPathExpressionException {
// You could cache/reuse xpath for better performance
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate(xpathExpresion,sourceNode,XPathConstants.NODESET);
ArrayList<Node> list = new ArrayList<Node>();
for(int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
list.add(node);
}
return list;
}
Add another method to build a Document from an XML input:
public Document buildDoc(InputStream is) throws Exception {
DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
DocumentBuilder parser = fact.newDocumentBuilder();
Document newDoc = parser.parse(is);
newDoc.normalize();
is.close();
return newDoc;
}
And then put it all together:
InputSource is = new InputSource(new StringReader("... your XML string here"));
Document doc = buildDoc(is);
List<Node> nodes = getNodes(doc, "/Name/Group/Package/Attribute");
for (Node node: nodes) {
// for the text body of an element, first get its nested Text child
Text text = node.getChildNodes().item(0);
// Then ask that Text child for it's value
String content = node.getNodeValue();
}
I hope I copied and pasted this correctly. I pulled this from a working class in an open source project of mine and cleaned it up a bit to answer your specific question.
Need to convert the format of output to UTF-8, because the output is not treating special characters.
Anyone have any idea how can this be done?
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
URL u = new URL("http://www.aredacao.com.br/tv-saude");
Document doc = builder.parse(u.openStream());
NodeList nodes = doc.getElementsByTagName("item");`
The problem is that the site returns <?xml version='1.0' encoding='iso-8859-1'?> but it should be returning <?xml version='1.0' encoding='UTF-8'?>.
One solution is to translate each element's text yourself:
static void readData()
throws IOException,
ParserConfigurationException,
SAXException {
DocumentBuilder builder =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
URL u = new URL("http://www.aredacao.com.br/tv-saude");
Document doc = builder.parse(u.toString());
NodeList nodes = doc.getElementsByTagName("item");
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
Element el = (Element) node;
String title =
el.getElementsByTagName("title").item(0).getTextContent();
title = treatCharsAsUtf8Bytes(title);
String description =
el.getElementsByTagName("description").item(0).getTextContent();
description = treatCharsAsUtf8Bytes(description);
System.out.println("title=" + title);
System.out.println("description=" + description);
System.out.println();
}
}
private static String treatCharsAsUtf8Bytes(String s) {
byte[] bytes = s.getBytes(StandardCharsets.ISO_8859_1);
return new String(bytes, StandardCharsets.UTF_8);
}
Another possibility is to write a subclass of FilterInputStream which replaces the erroneous <?xml prolog's encoding, but that is a lot more work, and I would only consider doing that if the document had a complex structure with many different elements such that translating each would be unwieldy.
I am using org.w3c.dom to parse an XML file. Then I need to return the ENTIRE XML for a specific node including the tags, not just the values of the tags. I'm using the NodeList because I need to count how many records are in the file. But I also need to read the file wholesale from the beginning and then write it out to a new XML file. But my current code only prints the value of the node, but not the node itself. I'm stumped.
public static void main(String[] args) {
try {
File fXmlFile = new File (args[0]);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList listOfRecords = doc.getElementsByTagName("record");
int totalRecords = listOfRecords.getLength();
System.out.println("Total number of records : " + totalRecords);
int amountToSplice = queryUser();
for (int i = 0; i < amountToSplice; i++) {
String stringNode = listOfRecords.item(i).getTextContent();
System.out.println(stringNode);
}
} catch (Exception e) {
e.printStackTrace();
}
}
getTextContent() will only "return the text content of this node and its descendants" i.e. you only get the content of the 'text' type nodes. When parsing XML it's good to remember there are several different types of node, see XML DOM Node Types.
To do what you want, you could create a utility method like this...
public static String nodeToString(Node node)
{
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
t.transform(new DOMSource(node), new StreamResult(sw));
return sw.toString();
}
Then loop and print like this...
for (int i = 0; i < amountToSplice; i++)
System.out.println(nodeToString(listOfRecords.item(i)));
I am trying to read the nodes dynamically according to the values sent from the jsp page. But somehow i am stuck in the for loop.
Suppose i have this xml:
<123>
<a1>A</a1>
<a2>B</a2>
<a3>C</a3>
</123>
And i am using this function to read nodes and get output:
try {
PdfReader pdfReader = new PdfReader(fileName);
PdfStamper pdfStamper =
new PdfStamper(pdfReader,new FileOutputStream(fileName));
String xmlRecords = XmlString;
DocumentBuilder db =
DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlRecords));
Document doc = db.parse(is);
NodeList nodes = doc.getElementsByTagName("123");
for(int i=1; i <= divlen; i++) {
for (int j = 0; j < nodes.getLength(); j++) {
Element element = (Element) nodes.item(j);
NodeList aval = element.getElementsByTagName("a"+i);
Element line = (Element) aval.item(0);
int avalue = Integer.parseInt(getCharacterDataFromElement(line));
}
}
pdfStamper.close();
}
where divlen is the total number of 'a' which is assigned by jsp page. But how do i run the for loop for a1 and a3 node if suppose i delete a2 node and send rest??
In your situation, I would create 3 list (one for each tag a1, a2, a3).
I would have then only the inner for loop (j), in which I put the Element in one of the list according to it's tag name.
Finally, after this loop, I would process each element of each list for whatever purpose I need to do.
Please help me to put element and text nodes into an array of Strings.
For example an .xml file has:
<soap:Envelope>
<soap:Body>
<ser:getTitle>
<!--Optional:-->
<ser:title>Meeting</ser:title>
</ser:getTitle>
<ser:getDiscription>
<!--Optional:-->
<ser:discription>this is the meeting</ser:discription>
</ser:getDiscription>
...
</soap:Body>
</soap:Envelop>
Now I want to place the values into the String[] key, value as follows:
key[0] = "title";
value[0] = "meeting";
key[1] = "discription";
value[1] = "this is the meeting";
... and so on.
Many thanks in advance!
You can use DOM to parse your input XML and use something like:
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.File;
public dumpXMLTags(...) {
String[] keys; // you would need that with appropriate size initialized
String[] values;
// Parse your XML file and construct DOM tree
File fXmlFile = new File(PATH_TO_YOUR_XML_FILE);
DocumentBuilder dBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
// Traverse DOM tree (make sure is not empty first, etc)
NodeIterator iterator = traversal.createNodeIterator(
doc.getDocumentElement(), NodeFilter.SHOW_ELEMENT, null, true);
int i = 0; // index to you key/value Array
for (Node n = iterator.nextNode(); n != null; n = iterator.nextNode()) {
keys[i] = ((Element) n).getTagName();
values[i] = ((Element)n).getNodeValue();
i++;
}
}
Alternatively you could use XPATH with the
//#* | //*[not(*)]
expression, as described here: Question 7199897
public static void main(String[] args) throws Exception {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
XPathFactory xpf = XPathFactory.newInstance();
XPath xp = xpf.newXPath();
NodeList nodes = (NodeList)xp.evaluate("//#* | //*[not(*)]", doc, XPathConstants.NODESET);
System.out.println(nodes.getLength());
for (int i=0, len=nodes.getLength(); i<len; i++) {
Node item = nodes.item(i);
System.out.println(item.getNodeName() + " : " + item.getTextContent());
}
}