Modify existing XML stylesheet processing instruction in Java - java

I'm reading an existing XML file and outputting it (using DOM).
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test"?>
<Books>
<Book name="MyBook" />
</Books>
But how do I modify the XML stylesheet? -> href here set "test".

Something like this should work (untested)
Element root = doc.getDocumentElement();
XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/processing-instruction('xml-stylesheet')";
ProcessingInstruction pi;
pi = (ProcessingInstruction)xpath.evaluate(expression, doc, XPathConstants.NODE);
pi.setData("type='text/xsl' href='foo.xsl'");

Thats a bit tricky, but why not read the file first into a String and do a replace before sending it via a stream into the dom parser.

Related

How to use java to get element of xml document, but in xml string format?

I have read some links on parsing xml document like below:
<inventory>
<book year="2000">
<title>Snow Crash</title>
<author>Neal Stephenson</author>
<publisher>Spectra</publisher>
<isbn>0553380958</isbn>
<price>14.95</price>
</book>
<book year="2005">
<title>Burning Tower</title>
<author>Larry Niven</author>
<author>Jerry Pournelle</author>
<publisher>Pocket</publisher>
<isbn>0743416910</isbn>
<price>5.99</price>
</book>
<!-- more books... -->
</inventory>
using DOM parsing:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(<uri_as_string>);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(<xpath_expression>);
however, their purpose are mostly to get VALUE of some node(s) by tag or by attribute from the document.
My purpose is to get the entire XML STRING of the node(s) back. For example, using Xpath /inventory/book[#year='2005'], i want to get the following xml back in a single string, i.e.
<book year="2005">
<title>Burning Tower</title>
<author>Larry Niven</author>
<author>Jerry Pournelle</author>
<publisher>Pocket</publisher>
<isbn>0743416910</isbn>
<price>5.99</price>
</book>
What is the API used for this purpose? And do i even need the DOM parsing in this case? Thanks,
COMMENT:
Maybe I should emphasize that I am asking this question as a XML related one, not a text file processing question. Concepts like 'tag', 'attribute', 'Xpath' still apply. The DOM model is not totally irrelevant. It's just that instead of getting the 'element' or value of a node, i want to get the whole node.
The given answers can not solve problems like: how to get a node in xml string format, given the node's Xpath representation, such as //book or /inventory/book[1]?
DOM parsers are designed to get values from the them not for actual file content.
You can use a simple file reader instead of XML.
Read line by line using a simple FileReader and check the line for the Condition and if the condition is met start the read content to concat as you want until the End of the node .
You can do it as
if(lineReadFromFile=="Your String Condition"){
//collect the desired file content here untill the end of the Node is found
}
You can simply read XML from file (consider it to be a normal text file) using FileReader. Simple apply the condition for example :
if(line.equals("<book year="2005"><title>Burning Tower</title>")) {
// retrieve/save the required content
}

Accessing an element in an XML file that has multiple elements of the same type

The following is a sample of what my xml sheet looks like and as you can see there is a possibility that there can be multiple genres, actors, directors, and companies. How would I specifically access each one.
Preferably answer this question with XPath and Java but if you don't know those and have an answer then tell me what you know.
<?xml version="1.0" encoding="UTF-8"?>
<movies>
<movie>
<title>Seven</title>
<actor>Pitt</actor>
<director>Fincher</director>
<genre>action</genre>
<genre>drama</genre>
<year>1995</year>
<company>Cecchi_Gori_Pictures</company>
<grading>79</grading>
</movie>
</movies>
//read a nodelist using xpath
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);

What are best algorithms/patterns to read xml files using [java] sax?

Let's suppose we have the following xml
<books>
<book>
<id>...</id>
<title>...</title>
<references>
<book>
<id>...</id>
<title>...</title>
</book>
</references>
<authors>
<author>
<id>...</id>
<name>...</name>
<written-books>
<book>
<id>...</id>
<title>...</title>
</book>
</written-books>
</author>
</authors>
<book>
</books>
What I do now is to use booleans to find out in what sections we are (book,references,authors,written-books). I do this on starte/end element event ,After that on characters event I check
if (qName.equals("id"){
if (writtenBooks){
}else if (authors){
}else if (references){
}else{
}
}else if ("title")...
But it doesn't seem to be too elegant. Is there a better solution?
According to my understanding what you have to do is read the XML and then process it. (Check the existence of the elements etc.) You can use Apache Axiom to read xml files and get the content easily. Then you can process it as you want.I will put a example code segment to get the content of the xml file using AXIOM.
//read the xml file
StAXOMBuilder builder = new StAXOMBuilder(xmlStreamReader);
OMElement endPointElem = builder.getDocumentElement();
// go though the xml elemetns and do whatever you want
Iterator children = endPointElem.getChildElements();
while (children.hasNext()) {
........................
.......
}
For more details This post will helpful to you

Merging different nodes of multiple XML files using JAVA

I have some xml files in an arrayList, for example A.xml B.xml
and I want to merge some of the nodes while the rest to remain as are using java. I'm new at using so I don't know how to do.
A xml:
<?xml version="1.0" encoding="UTF-8"?>
<nta>
<declaration>
bool A, B;
bool C;
</declaration>
<template>
<location id="1" x="10" y="10"/>
<transition>
<source ref="3"/>
</transition>
</template>
<system> system AND;</system>
</nta>
B.xml:
<?xml version="1.0" encoding="UTF-8"?>
<nta>
<declaration>
int f,k;
bool D;
</declaration>
<template>
<location id="100" x="40" y="89"/>
<transition>
<source col="9"/>
</transition>
</template>
<system> system OR;</system>
</nta>
And the output:
<?xml version="1.0" encoding="UTF-8"?>
<nta>
<declaration>
bool A, B;
bool C;
int f,k;
bool D;
</declaration>
<template>
<location id="1" x="10" y="10"/>
<transition>
<source ref="3"/>
</transition>
</template>
<template>
<location id="100" x="40" y="89"/>
<transition>
<source col="9"/>
</transition>
</template>
<system> system AND, OR;</system>
</nta>
Basically I want to merge the declaration and the system and the rest to be serial in the output xml file. How to do this using JAVA? Sorry for the long post!!!
In comparison with other available XML processing API, to me,
having DOMBuilder and SAXBuilder JDOM is better for:
Modifying the XML document
XML tree traversing and random access to any section
Merging documents
This is a complete working example for merging two XML document:
SAXBuilder builder = new SAXBuilder();
Document doc1 = builder.build(new File("E:\\XML1.xml"));
Document doc2 = builder.build(new File("E:\\XML2.xml"));
String rootName = doc1.getRootElement().getName();
Element newRoot = new Element(rootName);
Document newDoc = new Document(newRoot);
Element root1 = doc1.getRootElement();
Element root2 = doc2.getRootElement();
// creating declaraion element by merging the declaration content
Element declaration = new Element("declaration");
declaration.addContent(root1.getChildText("declaration"));
declaration.addContent(root2.getChildText("declaration"));
newRoot.addContent(declaration); // add declaration element to new document
newRoot.addContent(root1.getChild("template").clone());
// directly adding template from document XML1,
//after getting template child,
//it needs to be cloned to detached from its parent
newRoot.addContent(root2.getChild("template").clone());
// same for document XML2
/*** now code yourself for system element here ***/
XMLOutputter outputter = new XMLOutputter();
outputter.output(newDoc, System.out);
// output the new doc, pass your OutputStream to this function
You can use an xml parser such as dom to read the required parts (declaration and system) and later aggregate them to get your required out put.
you will get plenty of examples on reading and writing xml in java.
Parse XML as i write here or in any another way nad then use javax.xml.parsers.DocumentBuilder from here
to do what you want.Create a new XML doc.

Attributes in root element causes issues in XPath Evaluation in Java

I am trying to evaluate XPath Expression "/feed/entry/title" using:
NodeList nodeList = (NodeList) inputXMLxpath.evaluate("/feed/entry/title", xmlDoc,
XPathConstants.NODESET);
If the xmlDoc is like this:
<?xml version="1.0" encoding="UTF-8"?>
<feed>
<entry>...
<feed>
I get proper results, but when xmlDoc is like this:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-US">
<entry>...
</feed>
the result of XPath evaluation is always an empty list.
Can anybody tell the reason for this and suggest a solution such that I get proper result in second case also?
The xmlns-"...." is a namespace declaration, and it has the effect of changing the names of the elements in the document so that they are no longer called "feed" and "entry", but something more complicated. Google for "XPath default namespace declaration".

Categories