Need to add #color attribute with color name in each nested 'dn' element under the 'dyn' - xslt-2.0

I need to add #color attribute with color name in each nested 'dn' element if position is even, #color attribute to the second, fourth, sixth etc. dn child of each level and as well as dn element following-sibling of dn element
I try with position function but unable to get solution
Please look into this and Thanks in advance
Input XML file:
<dyn>
<dn></dn>
<dn></dn>
<dn>
<dn></dn>
<dn></dn>
<dn>
<dn></dn>
<dn></dn>
<dn></dn>
</dn>
</dn>
</dyn>
XSLT file:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dyn">
<dyn>
<xsl:choose>
<xsl:when test="following::dn/position() mod 2 = 0">
<dn>
<xsl:attribute name="color">
<xsl:value-of select="'red'"/>
</xsl:attribute>
</dn>
</xsl:when>
<xsl:otherwise/>
</xsl:choose>
<xsl:apply-templates/>
</dyn>
</xsl:template>
</xsl:stylesheet>
Expected output:
<dyn>
<dn></dn>
<dn color="red"></dn>
<dn>
<dn></dn>
<dn color="red">
</dn>
<dn>
<dn color="red"></dn>
<dn></dn>
<dn color="red"></dn>
<dn>
</dn></dn>
</dn>
</dyn>

Your verbal description sounds as if you want
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="dn[position() mod 2 = 0]">
<xsl:copy>
<xsl:attribute name="color">red</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
This gives the output
<dyn>
<dn/>
<dn color="red"/>
<dn>
<dn/>
<dn color="red"/>
<dn>
<dn/>
<dn color="red"/>
<dn/>
</dn>
</dn>
</dyn>
which has the right attributes for the first two levels but on the third level it gives the second dn child that color="red" attribute while your wanted output, for reasons I have so far not understood, there adds the attribute to the first and third dn child.

Related

How to remove test:ws element from x:expect result in XSpec

Expected result throw by xspec:
<nl/>
<test:ws xmlns:test="http://www.jenitennison.com/xslt/unit-test">
</test:ws>
Expected result i want is our desired output element:
<nl/>
You Need to do 3 things in your XSLT:
Add namespace xmlns:test="http://www.jenitennison.com/xslt/unit-test"
Exclude namespace exclude-result-prefixes="xs test"
Write empty template for test:ws <xsl:template match="test:ws"/>
XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<nl/>
<test:ws xmlns:test="http://www.jenitennison.com/xslt/unit-test"></test:ws>
</root>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:test="http://www.jenitennison.com/xslt/unit-test"
exclude-result-prefixes="xs test" version="2.0">
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="test:ws"/>
</xsl:stylesheet>
OUTPUT:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<nl/>
</root>
See below mentioned link for reference:
https://xsltfiddle.liberty-development.net/jyH9rNa

Parameter values for saxon not getting in the xslt

I am not getting the parameter value (var in this case) into the XSLT when I tried to convert an XML document with saxon.
I got the following error in the terminal:
XPST0008: XPath syntax error at char 4 on line 8 in {$var}:
Variable $var has not been declared
Failed to compile stylesheet. 1 error detected.
I tried the following in the terminal (Ubuntu 14.04):
java -jar saxon-9.1.0.8.jar -s:x.xml -xsl:x.xsl -o:x.txt var="name"
My XSL stylesheet (x.xsl) is:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:template match="//files">
<xsl:value-of select="."/>
<xsl:value-of select="$var"/>
</xsl:template>
</xsl:stylesheet>
The XML (x.xml) is:
<files>
Var =
</files>

Ant xslt task output to stdout

Using the <xslt> task in ant, how do I get the output to generate to stdout?
My XSLT is generating multiple files through xsl:result-document and the normal output is just status information that I'd like to show up with normal Ant output. Ant seems to force me to supply a destdir= or an out= parameter.
Ant 1.8.2 with Saxon 9
Yes ant does this. However XSLT has the element which you can use to get output on the stdout :)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="types" match="a" use="text()"/>
<xsl:template match="/">
<result>
<xsl:message terminate="no">I am a message from xslt!</xsl:message>
</result>
</xsl:template>
</xsl:stylesheet>
Output :
build:
[xslt] Processing C:\Users\Stefanos\Documents\Visual Studio 2010\Projects\stackOverflow\stackOverflow\test.xml to C:\Users\Stefanos\Documents\Vis
ual Studio 2010\Projects\stackOverflow\stackOverflow\out.xml
[xslt] Loading stylesheet C:\Users\Stefanos\Documents\Visual Studio 2010\Projects\stackOverflow\stackOverflow\test.xslt
[xslt] I am a message from xslt!
BUILD SUCCESSFUL
Total time: 0 seconds
Hope it helps!
I recently had a similar scenario; an Ant script with an XSLT task where the style sheet transform generated multiple files using <xsl:result-document>. Since the Ant XSLT task requires the destdir attribute (unless the out attribute has been specified), I used known temp file(s) for the out destination and then implemented a “cleanup” task which deleted the temp file(s).
<target name="removeTemporaryFiles" description="remove temporary files">
<delete file="${workspace}/temp.xhtml"></delete>
…
</target>

Is there an ant command which lists all targets in a file and there depends?

Is there an ant command which lists all targets in a file and there depends?
Right now I just use a little power shell script to match lines that contain <target but its not really a good solution. Is there any sort of built in command?
The closest is ant -p (or ant -p -v to get more information). This won't list the target dependencies, but I don't see it as a problem: dependencies are not important for the end user (they just tell how the target works).
What's important is what the target does, which is what should be in its description:
<target name="foo" depends="bar" description="Does the foo operation">
...
</target>
I what you really want is the target dependencies, then reading the xml file is the best you can do.
No there isn't but you can do it like this :
<target name="list.targets">
<xslt in="${basedir}\{build.file}"
out="tmp"
style="${display.targets.xsl}">
</xslt>
<delete file="tmp"/>
</target>
Where ${display.targets.xsl} points to the following .xsl file :
<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output method='text'/>
<xsl:template match="/">
<xsl:for-each select="//target">
<xsl:sort data-type="text" select="#name"/>
<xsl:message terminate="no">
Target : <xsl:value-of select="#name"/><xsl:if test="#depends"> depends on : <xsl:value-of select="#depends"/>
</xsl:if>
<xsl:if test="#description">
Description : <xsl:value-of select="#description"/>
</xsl:if>
</xsl:message>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
And ${basedir}{build.file} points to your current build.xml file. The output will be something like this :
[xslt] Loading stylesheet D:\Tools\StackOverFlow\test.xslt
[xslt]
[xslt] Target : build
[xslt]
[xslt] Target : modify.trs
[xslt] Description : Modifies .trs file targets
[xslt]
[xslt] Target : regex depends on : modify.trs
Depending on your build.xml of course.
If you search for "ant dependency graph", you'll find some suggestions on how to produce a .dot file from your build file which can be rendered into a visual graph by GraphViz.

How can I turn the structure of an XML file into a folder structure using ANT

I would like to be able to pass an XML file to an ANT build script and have it create a folder structure mimicking the nodal structure of the XML, using the build files parent directory as the root.
For Example using:
<root>
<folder1>
<folder1-1/>
</folder1>
<folder2/>
<folder3>
<folder3-1/>
</folder3>
</root>
ant would create:
folder1
-folder1-1
folder2
folder3
-folder3-1
I know how to create a directory, but i'm not sure how to have ANT parse the XML.
One option would be to use the xslt task to do the heavy lifting. For example, generate a second ant script and invoke it.
build.xml:
<project default="mkdirs">
<target name="mkdirs">
<xslt style="mkdir.xslt" in="dirs.xml" out="mkdir.build.xml"/>
<ant antfile="mkdir.build.xml"/>
</target>
</project>
Place mkdir.xslt in the same directory as build.xml:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="text()"/>
<xsl:template match="root">
<project><xsl:text>
</xsl:text>
<xsl:apply-templates/>
</project>
</xsl:template>
<xsl:template match="*">
<mkdir>
<xsl:attribute name="dir">
<xsl:for-each select="ancestor::*">
<xsl:if test="position() != 1">
<xsl:value-of select="name()"/>
<xsl:text>/</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:value-of select="name()"/>
</xsl:attribute>
</mkdir><xsl:text>
</xsl:text>
<xsl:apply-templates/>
</xsl:template>
</xsl:transform>
Example mkdir.build.xml output from the xslt task:
<?xml version="1.0" encoding="UTF-8"?><project>
<mkdir dir="folder1"/>
<mkdir dir="folder1/folder1-1"/>
<mkdir dir="folder2"/>
<mkdir dir="folder3"/>
<mkdir dir="folder3/folder3-1"/>
</project>
I'm not fluent in XSLT, so it might be possible to improve on the for-each loop.

Resources