I have a xslt transformation from xml to pdf using apache fop. Whether is possible to add codnition to xslt transormation? I want to not display column in result pdf if all values in column equals zero. It's possible?
Yes, it is possible. In fact, you can do declarative/functional programming logic with XSLT using templates, functions and conditionals. Since you did not provide any example code, I will suppose that you have a table element in your xslt, and you want to show it only if there is some non-zero value to be displayed.
In this case, you should use an recursive template to walk along the list in your xml, and keep checking with XPath if the values are equal to zero. If you find zero, call this same template for the next value, if not, call the template that builds the table for you.
Notice that to use condition, you can use xsl:for-each, xsl:when or xsl:if elements to make the decision given the XPath expression. The xsl:template is used for iterating recursively with parameters, given that instance variables do not exist in xsl.
Related
I have a xml file like a single database table, is there a way I can get "listpos"-rows of certain fields, ie. only "type" and "objName" ?
<listpos lfdNr="0001" reihe="20140626143443">
<type>Akt</type>
<objName>2#25.6.2014#40801#de</objName>
<laborOrt>au</laborOrt>
...
</listpos>
<listpos lfdNr="0002" reihe="20140626181936">
<type>Akt</type>
<objName>2#25.6.2014#40802#de</objName>
<laborOrt>au</laborOrt>
...
</listpos>
...
So the output should be
<listpos>
<type>Akt</type>
<objName>2#25.6.2014#40801#de</objName>
</listpos>
<listpos>
<type>Akt</type>
<objName>2#25.6.2014#40802#de</objName>
</listpos>
...
Writing this it comes to my mind it might be a job for xslt?
The whole thing I do, is trying to make django-xml work together with django_tables2 ...
Yes, by using XPath you can get that data pretty easily.
You navigate to the appropriate elements using Expressions.
For the data you're trying to extract (assuming you wanted to access all "type" and "objName" Elements), those would be "//listpos/type" and "//listpos/objName"
Those would get you the right nodes from which you can extract the content.
I'm trying to output a line of text when I reach a specific line number on the output. Is there a function withing bi-publisher that will allow me to do that?
The function position() will give you the XML record number of the line you are on. You can do math and if statements on that.
You may also be interested in created a "group number" as I would call it. Where, in the data definition or SQL which is used to create the XML File, you create a field on the line level that increments by 1 for every X number of records. You can then use that in your template as a for-each-group grouping field.
I have a stylesheet that I developed in version 1.0. I needed to convert to version 2.0 to take advantage of some additional features. Now however, when I use the following syntax I get all the results instead of just the first one. This worked in v1.0 but does not work in v2.0:
//elementName[1]
Is there a simple fix?
That XPath will return the same nodes in both versions (namely all the elementName elements in the document that are the first child with that name in their respective parent elements), but
<xsl:value-of select="//elementName[1]"/>
will give different results. In XSLT 1.0 the behaviour of value-of when given a set of nodes is to output the value of the first node in the set in document order and ignore the others, but in 2.0 it will output the values of all of them, separated by spaces. If you want to restrict to the first item in the sequence you should do so explicitly with (....)[1].
Yes, the fix is simple...
(//elementName)[1]
This will give you the first occurrence. Your previous xpath was every elementName that was the first elementName child of its parent.
A good example from the spec:
NOTE: The location path //para[1] does not mean the same as the
location path /descendant::para[1]. The latter selects the first
descendant para element; the former selects all descendant para
elements that are the first para children of their parents.
Using XSLT how do we render CDATA tag?
In xslt I dont want to create CDATA tag using text or declaring in xml
output tag using cdata-section-elements,
it should read it dynamically from input, if element value is around CDATA than
then xslt should render the same, as shown below
Input:
<A><![CDATA[Hello World]]></A>
XSLT Output :
<A><![CDATA[Hello World]]></A>
The data model XSLT/XPath/XQuery operate on does not know any CDATA sections so you can't simply preserve them as the tree you operate on simply contains a text node in both cases (i.e. for <foo>a & b</foo> and <foo><![CDATA[a & b]]></foo> the tree is a foo element containing a single text child node with the string value a & b).
So there is no way in pure XSLT to achieve what you want, unless you pre-process the input to convert CDATA sections into some structure like elements the XSLT data model allows you to detect and distinguish. Andrew Welch has http://andrewjwelch.com/lexev/ to do that in a Java environment.
Thus if you use an XSLT 2.0 processor like Saxon 9 with Java you could use that approach.
I have done a search for all nodes that have an attribute containing (substring) a String. These nodes can be found at different levels of the tree, sometimes 5 or 6 levels deep. I'd like to know what parent/ancestor node they correspond to at a specified level, 2 levels deep. The result for the search only should be much greater than the results for the corresponding parents.
EDIT to include code:
/xs:schema/xs:element/descendant::node()/#*[starts-with(., 'my-search-string-here')]
EDIT to clarify my intent:
When I execute the Xpath above sometimes the results are
/xs:schema/xs:element/xs:complexType/xs:attribute or
/xs:schema/xs:element/xs:complexType/xs:sequence/xs:element or
/xs:schema/xs:element/xs:complexType/xs:complexContent/xs:extension/xs:sequence/xs:element
These results indicate a place in the Schema where I have added application specific code. However, I need to remove this code now. I'm building an "adapter" schema that will redefine the original Schema (untouched) and import my schema. The String I am searching for is my prefix. What I need is the #name of the /xs:schema/node() in which the prefix is found, so I can create a new schema defining these elements. They will be imported into the adapter and redefine another schema (that I'm not supposed to modify).
To reiterate, I need to search all the attributes (descendants of /xs:schema/xs:element) for a prefix, and then get the corresponding /xs:schema/xs:element/#name for each of the matches to the search.
To reiterate, I need to search all the attributes (descendants of /xs:schema/xs:element) for a prefix, and then get the corresponding /xs:schema/xs:element/#name for each of the matches to the search.
/
xs:schema/
xs:element
[descendant::*/#*[starts-with(., 'my-search-string-here')]]/
#name
This should do it:
/xs:schema/xs:element[starts-with(descendant::node()/#*, 'my-search-string-here')]
You want to think of it as
select the xs:elements which contain a node with a matching attribute
rather than
select the matching attributes of descendant nodes of xs:elements, then work back up
As Eric mentioned, I need to change my thought process to select the xs:elements which contain a node with a matching attribute rather than select the matching attributes of descendant nodes of xs:elements, then work back up. This is critical. However, the code sample he posted to select the attributes does not work, we need to use another solution.
Here is the code that works to select an element that contains and attribute containing* (substring) a string.
/xs:schema/child::node()[descendant::node()/#*[starts-with(., 'my-prefix-here')]]