count all occurences of xsl:result-document in a given stylesheet - java

I have an issue with part of my application in which I have some utility classes for xslt transformation functionality. I use SaxonHE as XSLT Transformer implementation.
My helper class has a function: URL mapFile(URL input, String stylesheetPath).
That takes the URL of one XML-File as input and returns a URL for the created XML-File. It handles the initialization and execution of the XSLT transformation.
But a stylesheet could theoretically create multiple XML files with xsl:result-document tags and I would like my utility class to be able to recognize if the given stylesheet will do that and handle it properly.
My idea was to analyse/parse the stylesheet from within my Java code and count all occurences of xsl:result-document.
With the values of the href-attributes, I would also know where the stylesheet creates the output XML files since I want to return a URL that points to their location.
So my changed utility method would be: List<URL> mapFile(URL input, String stylesheetPath) and return a number of URLs based on how many files are created by the given stylesheet.
But I have no idea how to do this in Java code and all my google searches concerning counting elements in a xsl stylesheet resulted in explanations how to count XML elements of the input XML from inside the stylesheet, which is not what I want to do.
EDIT: I ended up not doing any parsing of the stylesheet at all. I just create a folder and if someone writes a stylesheet that doesnt put all result files in that folder then it is their fault if they dont get a URL back for that result document . A hacky solution but it works for my use-case.

For a single-module stylesheet it's very simple: just execute the XPath expression count(//xsl:result-document).
For a stylesheet with multiple modules it gets more complicated because you have to follow xsl:include and xsl:import references, and more particularly, you have to detect cycles in the include/import graph so you don't go into an infinite loop.
You could export the stylesheet to a SEF file and execute count(//*:resultDoc) on the SEF file. Unfortunately that's Saxon-EE which will cost you money, but then writing the code by hand will cost you money too...
But actually you've asked for two different things. First you say you want to know the number of xsl:result-document instructions, then you say you want to know how many result documents are created. These aren't the same thing, because you don't know how often each xsl:result-document instruction is executed.
I suspect you can solve the problem by registering a result document handler with Saxon and using it to monitor calls on xsl:result-document at run-time.

Related

How to limit scope for XPath

I need to parse relatively big XML files on Android.
Some node internal structure contains HTML tags, for some other nodes I need to pull content from different depth levels. Therefore, instead of using XmlPullParser I plan to:
using XPath, find the proper node
using 'getElementsByTagName' find appropriate sub-node(s)
extract information and save it in my custom data objects.
The problem I have is performance. The way how I open file is following:
File file = new File(_path);
FileInputStream is = new FileInputStream(file);
XPath xPath = XPathFactory.newInstance().newXPath();
NamespaceContext context = new NamespaceContextMap("def", __URL__);
xPath.setNamespaceContext(context);
Object objs = xPath.evaluate("/def:ROOT_ELEMENT/*,
new InputSource(is), XPathConstants.NODESET);
Even though I need to get few strings that are in the very beginning of the XML file, it looks like XPath parses WHOLE xml file and put it in DOM structure.
In some cases I need access to full object and it is ok to have operation running few seconds for few megabyte file.
In other cases - I only need to get few nodes and don't want users to wait for my program to perform a redundant parsing.
Q1: What is the way to get some parts of XML file without parsing it in full?
Q2: Is there any way to restrict XPath from scanning/parsing WHOLE XML file? For instance: scan till 2nd level of depth?
Thank you.
P.S. In one particular case, XML file represents FB2 file format and if you have any specific tips that could resolve my problem for fb2-files parsing, please fill free to add additional comments.
I don't know too much about the XML toolset available for android, except to know that it's painfully limited!
Probably the best way to tackle this requirement is to write a streaming SAX filter that looks for the parts of the document you are interested in, and builds a DOM containing only those parts, which you can then query using XPath. I'm a bit reluctant to advise that, because it won't be easy if you haven't done such things before, but it seems the right approach.

XSLT extraction of all input possible xpaths

I have really complex xsl (20 000 rows xsl file!) file which processes input file XML and makes output XML file.
I would like to extract all input file xpaths which are possible processed in the xsl. So I would like somehow to have a extraction of all (input)xpaths which are concerned in the XSL.
For that purpose I would like to find java API or tool which is able to give me this information with single passing of the XSL file. Are there such APIs or tools?
Regards
Aurel
Technically, that's easy- every node's processed in some way. I'm guessing what you really want is "what's specifically processed by a template that's defined in the stylesheet."
To do that, just add the identity template to the very bottom of your stylesheet- anything which hasn't already been processed already will be processed by that, and you can add in an <xsl:message> instruction to output whatever you need there. I'm fairly sure you'll find examples of how to generate the XPath of the context node around, that's been asked a few times.
EDIT: I forgot to mention- technically this will give you the inverse of what you asked for, it'll tell you what nodes are NOT processed. Hopefully you'll be able to use that to achieve the same goal though.

how to fetch value in xml file from jsp?

Hey i have a situation in which i need to pass some variable value in jsp to xml file.
for example if i have int a = 10;
and i want to pass value of "a" to xml file which is something like:-
<graph caption='Estimated Renewal Cost' xAxisName='Year' yAxisName='Units (US Dollars)' showNames='1' decimalPrecision='0' formatNumberScale='0'>
<set name='Backlog' value='19273773' color='AFD8F8' />
</graph>
so in i want the value of "a" to be brought at value attribute of set tag in xml.
Actually i'm using fusion charts to generate graph and want to have dynamic graph which may change according to my jsp page. And as far as i know fusion charts only accept data in xml format.
I have no experience with xml.
Your question doesn't make much sense. An XML file is just that: a file. It doesn't contain any executable or interpreted statement.
You probably want to dynamically generate an XML file (or stream), but unless the output generated by the JSP is this XML file (after all, JSPs typically generate (X)HTML, and can be used to generate other kinds of XML documents), it's not really a task that a JSP should do. A servlet is the place where such a task should be done.
If you want to generate an XML document, you have many choices: DOM, JDOM, dom4j, JAXB, or even plain string concatenation (although I would not recommend it, except if all you need to do is generating such a small document with only one dynamic attribute).

Best practice to parse xml file with same content but based on different schemas

I need to parse xml files from two sources. Both xml files contain the same content but each source uses their own schemas. This means the values that i want to extract from the xml file will be stored in different element names depending on the source of the file.
Here is an example - Assume i am only interested in the "name" of a product.
Source 1
-------------------------
<item>
<itemname>Camera</itemname>
<itemprice>20</itemprice>
</item>
Source 2
-------------------------
<productList>
<productName>Camera</productname>
<ProductPrice>20</productprice>
</productList>
To parse the above i have to know the source of the xml file and then either do a
getElementsByTagName("itemname");
or
getElementsByTagName("productName");
My original plan was to have a different parser for each source's xml file but i am thinking that maybe i could write a generic parser if i specify the path to the element i need. The benefit of this is that i can then process any xml file from any source without having to modify the parser.
What i am thinking of doing is to store the path to the element on to a properties file. i.e.
source1.name="itemname"
source2.name=productName
The generic parser would then just retrieve the element based on the name i provide it. This will probably work but i am thinking that if i am interested in more than one element it might be cumbersome to maintain it via a properties file.
Is there a better way to resolve the above? Please note that One restriction that i am limited to is that the target platform for this is JDK 1.4 so xpath etc would not work.
The ideal solution is XPath. No matter how different the XML inputs are, you can store an XPath for each as a string in a properties file. There are several XPath-compliant parsers that work with JDK 1.4.
If element names follow a convention (*Name, *Price), you could write a generic parsing function using wildcards and XPath. Or you could write it based on tag orders if they are always the same (you can do this without XPath).

Parsing a xml file using Java

I need to parse a xml file using JAVA and have to create a bean out of that xml file after parsing .
I need this while using Spring JMS in which producer is producing a xml file .First I need to read the xml file and take action according .
I read some thing about parsing and come with these option
xpath
DOM
Which ll be the best option to parse the xml file.
did you check JAXB
There's three ways of parsing an XML file, SAX, DOM and StAX.
DOM will parse the whole file and build up a tree in memory - great for small files but obviously if this is huge then you don't want the entire tree just sitting in memory! SAX is event based - it doesn't load anything into memory per-se but just fires off a series of events as it reads through the file. StAX is a median between the two, the application moves the cursor forward as it needs, grabbing the data as it goes (so no event firing or huge memory consumption.)
What one you use will really depend on your application - all have built in libraries since Java 6.
Looks like, you receive a serialized object via Java messaging. Have a look first, how the object is being serialized. Usually this is done with a library (jaxb, axis, ...) and you could use the very same library to create a deserializer.
You will need:
The xml schema (a xsd file)
The Java bean class (very helpful, it should exist)
Then, usually the library will create all helper classes and files and you don't have to care about parsing.
if you need to create an object, just extract the needed properties and go on...
I recommend using StaX, see this tutorial for more information.
Umh..there are several ways you can parse an xml document to into memory and work with it. You mentioned DOM. DOM actually holds uploads the whole document into memory and then allows you to move between different branches of the XML document.
On the other hand, you could use StAX. It works similar to DOM. The only difference is that, it streams the content of the XML document thus allowing better allocation of memory. On the other hand, it does not retain the information that has already been read.
Look at : http://download.oracle.com/javaee/5/tutorial/doc/bnbem.html It gives details about both parsing methods and example code. Hope that helps.

Categories