XSL help printing variables from multiple nodes on a single row - xslt

Very new to XSL (and XML for that matter), but I need to step though an XML and print the required selections on a single line, for each run in the xml data. The problem I am having is that one selection (time) is in a different node than the other 7. I can't yet figure out what I need to do, to get the desired output. Here is my data and stylesheet if anyone wouldn't mind helping me out:
XSL STYLESHEET
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Storage IO</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Time</th>
<th>Reads per Second</th>
<th>Writes per Second</th>
<th>KB Read per Second</th>
<th>KB Written per Second</th>
<th>Read Cache Hit %</th>
<th>Write Cache Hit %</th>
<th>Sequential Read %</th>
<th>Write Pending Tracks</th>
</tr>
<xsl:for-each select="/SymCLI_ML/Statistics/Request_Totals">
<tr>
<td><xsl:value-of select="time"/></td>
<td><xsl:value-of select="r_per_second"/></td>
<td><xsl:value-of select="w_per_second"/></td>
<td><xsl:value-of select="kb_r_per_second"/></td>
<td><xsl:value-of select="kb_w_per_second"/></td>
<td><xsl:value-of select="r_cache_hit_pct"/></td>
<td><xsl:value-of select="w_cache_hit_pct"/></td>
<td><xsl:value-of select="sequential_r_pct"/></td>
<td><xsl:value-of select="wp_tracks"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
XML FILE
<?xml version="1.0" standalone="yes" ?>
<?xml-stylesheet type="text/xsl" href="totals.xsl"?>
<SymCLI_ML>
<Statistics>
<time>Mon Mar 19 2012 15:24:53</time>
</Statistics>
<Statistics>
<time>Mon Mar 19 2012 15:25:04</time>
<Request>
<dev_name>0052</dev_name>
<pd_name>Not Visible</pd_name>
<r_per_second>0</r_per_second>
<w_per_second>0</w_per_second>
<kb_r_per_second>0</kb_r_per_second>
<kb_w_per_second>0</kb_w_per_second>
<r_cache_hit_pct>N/A</r_cache_hit_pct>
<w_cache_hit_pct>N/A</w_cache_hit_pct>
<sequential_r_pct>N/A</sequential_r_pct>
<wp_tracks>0</wp_tracks>
</Request>
<Request>
<dev_name>1AAF</dev_name>
<pd_name>Not Visible</pd_name>
<r_per_second>0</r_per_second>
<w_per_second>0</w_per_second>
<kb_r_per_second>0</kb_r_per_second>
<kb_w_per_second>0</kb_w_per_second>
<r_cache_hit_pct>N/A</r_cache_hit_pct>
<w_cache_hit_pct>N/A</w_cache_hit_pct>
<sequential_r_pct>N/A</sequential_r_pct>
<wp_tracks>0</wp_tracks>
</Request>
<Request>
<dev_name>1B2F</dev_name>
<pd_name>Not Visible</pd_name>
<r_per_second>0</r_per_second>
<w_per_second>0</w_per_second>
<kb_r_per_second>0</kb_r_per_second>
<kb_w_per_second>0</kb_w_per_second>
<r_cache_hit_pct>N/A</r_cache_hit_pct>
<w_cache_hit_pct>N/A</w_cache_hit_pct>
<sequential_r_pct>N/A</sequential_r_pct>
<wp_tracks>0</wp_tracks>
</Request>
<Request_Totals>
<r_per_second>1032</r_per_second>
<w_per_second>1309</w_per_second>
<kb_r_per_second>28003</kb_r_per_second>
<kb_w_per_second>19347</kb_w_per_second>
<r_cache_hit_pct>74</r_cache_hit_pct>
<w_cache_hit_pct>99</w_cache_hit_pct>
<sequential_r_pct>6</sequential_r_pct>
<wp_tracks>9994</wp_tracks>
</Request_Totals>
</Statistics>
</SymCLI_ML>

Try using either:
<td><xsl:value-of select="../time"/></td>
or
<td><xsl:value-of select="/*/Statistics[1]/time"/></td>
depending on which <time> value you're trying to retrieve.

Related

How to transform all same element in a node

In below xml file contain many author elements. I have mentioned in xslt and display the first element only. I want to show all author elements. Kindly provide the xslt coding for element not in the text will be shown in browser.
XML Code:
<?xml version="1.0" encoding="US-ASCII" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="view.xsl"?>
<!DOCTYPE WileyML3G [
<!ENTITY % wileyml3g.ent SYSTEM "http://v.wiley.com:3535/dtds/wileyml3g/wiley.ent">
%wileyml3g.ent;
]>
<bibliography xml:id="aic16349-bibl-0001" style="numbered" cited="no">
<title type="main">REFERENCE<!--<QUERY xml:id="Q2"><p>References "3–35" were not cited anywhere in the text. Please provide a citation. Alternatively, delete the items from the list.</p></QUERY>--></title>
<bib xml:id="aic16349-bib-0001">
<citation type="journal" xml:id="aic16349-cit-0001"><!--<QUERY xml:id="Q3"><p>Reference "1" is not cited in the text. Please indicate where it should be cited; or delete from the reference list.</p></QUERY>-->
<author><familyName>Deer</familyName> <givenNames>TR</givenNames></author>, <author><familyName>Provenzano</familyName> <givenNames>DA</givenNames></author>, <author><familyName>Hanes</familyName> <givenNames>M</givenNames></author>, et al. <articleTitle>The Neurostimulation Appropriateness Consensus Committee (NACC) Recommendations for Infection Prevention and Management</articleTitle>. <journalTitle>Neuromodulation.</journalTitle> <pubYear year="2017">2017</pubYear>;<vol>20</vol>(<issue>1</issue>):<pageFirst>31</pageFirst>‐<pageLast>50</pageLast>.</citation>
</bib>
XSLT Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h1>HTML VIEW</h1>
<table border="1" cellpadding="10px">
<tr>
<th>Authors</th>
<th>Year</th>
<th>Article_Title</th>
<th>Journal_Title</th>
<th>Volume</th>
<th>Issue</th>
<th>First_Page</th>
<th>Last_Page</th>
</tr>
<xsl:for-each select="bibliography/bib/citation">
<tr>
<td><span style="background-color:skyblue;"><xsl:value-of select="author"/></span>, </td>
<td><xsl:value-of select="pubYear"/></td>
<td width="75%"><xsl:value-of select="articleTitle"/></td>
<td width="25%"><xsl:value-of select="journalTitle"/></td>
<td><xsl:value-of select="vol"/></td>
<td><xsl:value-of select="issue"/></td>
<td><xsl:value-of select="pageFirst"/></td>
<td><xsl:value-of select="pageLast"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
You have tagged the question as XSLT 2.0 and if you really use an XSLT 2.0 processor and use version="2.0" in your stylesheet then <xsl:value-of select="author"/> would output all selected author child elements and you could even use <xsl:value-of select="author" separator=", "/> to have the different authors separated by ,. If you use XSLT 1.0 then use <xsl:appy-templates select="author"/> and <xsl:template match="author"><xsl:if test="position() > 1">, </xsl:if></xsl:value-of select="."/></xsl:template> or use xsl:for-each if you prefer that.
As #Martin suggestion if you really want to use 1.0 then you have to go with for-each author like:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h1>HTML VIEW</h1>
<table border="1" cellpadding="10px">
<tr>
<th>Authors</th>
<th>Year</th>
<th>Article_Title</th>
<th>Journal_Title</th>
<th>Volume</th>
<th>Issue</th>
<th>First_Page</th>
<th>Last_Page</th>
</tr>
<xsl:for-each select="bibliography/bib/citation">
<tr>
<td>
<span style="background-color:skyblue;">
<xsl:for-each select="author">
<xsl:value-of select="."/>
<xsl:if test="following-sibling::author"><xsl:text>, </xsl:text></xsl:if>
</xsl:for-each>
</span>
</td>
<td><xsl:value-of select="pubYear"/></td>
<td width="75%"><xsl:value-of select="articleTitle"/></td>
<td width="25%"><xsl:value-of select="journalTitle"/></td>
<td><xsl:value-of select="vol"/></td>
<td><xsl:value-of select="issue"/></td>
<td><xsl:value-of select="pageFirst"/></td>
<td><xsl:value-of select="pageLast"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Or it will be done very easy while working with 2.0 like:
Need to change the XSLT version from 1.0 to 2.0
Use #seperator with , in value-of author.
HTML VIEW
Authors
Year
Article_Title
Journal_Title
Volume
Issue
First_Page
Last_Page

How to display the text of a hyperlink in SharePoint

I am trying to display the text of a hyperlink. The hyperlink is obtained from a query, and its column type is Publishing Hyperlink.
This code <xsl:value-of select="$Link" /> display the full link
File 1
How can I just display the text of the link?
File
Is there some code like <xsl:text-of select="$Link" /> or something else?
You can use
<xsl:value-of select="YOUR ANCHOR TEXT TAG IN XML HERE"/>
Replace your link text tag name you have given in your xml file with "YOUR ANCHOR TEXT TAG IN XML HERE"
This will display the anchor text for sure.
See the example below
XML Code
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<link>http://www.google.com</link>
<text>google</text>
</cd>
<cd>
<link>http://www.yahoo.com</link>
<text>yahoo</text>
</cd>
</catalog>
XSLT Code
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Anchor Link</th>
<th style="text-align:left">Anchor Text</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="link"/></td>
<td><xsl:value-of select="text"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Output:
Please click on the url to see output
https://i.stack.imgur.com/Dp24I.jpg
According DataSource details:
Source
Using:
<xsl:text-of select="$Link.desc" />
Should work.

Same xpath works on command line but not in xslt

I'm a beginning user of xslt and xpath. Using an xpath on a command line (Ubuntu 14.04) with a xml file works, but the very same xpath in an xslt file returns nothing. I'm working with Juniper Junos xml files. Any suggestions?
Thanks,
George
The xml file begins with:
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" xmlns:junos="http://xml.juniper.net/junos/12.3R8/junos">
<interface-information xmlns="http://xml.juniper.net/junos/12.3R8/junos-interface" junos:style="normal">
<physical-interface>
<name>fe-0/1/0</name>
<logical-interface>
<name>fe-0/1/0.0</name>
...
The command line that works in Ubuntu 14.04 is:
xpath -e "/rpc-reply/interface-information/physical-interface/logical-interface/name" interfaces.xml
The xslt file is:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Interfaces</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Name</th>
</tr>
<xsl:for-each select="/rpc-reply/interface-information/physical-interface/logical-interface">
<tr>
<td><xsl:value-of select="name"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The problem here is quite simple. You are not using namespaces in your XPaths. Apparently your command line utility doesn't care, or evaluates XPaths based on the elements' QNames ignores default namespaces and does some other non-standard handling of namespaces as well.
The solution:
Declare prefixes at the top of your stylesheet:
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:nbase="urn:ietf:params:xml:ns:netconf:base:1.0"
xmlns:junosi="http://xml.juniper.net/junos/12.3R8/junos-interface"
>
use those prefixes in your XPaths:
<xsl:for-each select="/nbase:rpc-reply/junosi:interface-information
/junosi:physical-interface/junosi:logical-interface">
<tr>
<td><xsl:value-of select="junosi:name"/></td>
</tr>
</xsl:for-each>

XSLT display data in repeated columns

I need to create XSLT to show results in repeated columns to avoid scrolling in the page.
While checking for a solution i found an example from W3schools -
http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog
The above example shows how to add multiple columns using XSLT. But my requirement is different. If we take the same example, i want data to be displayed as below
Title Author Title Author
A-Title Gregory D-Title Ford
B-Title Dr.John E-Title Sean
C-Title Bellucci F-Title Steven
To avoid scrolling for the Users I need to split the data in two columns. Also the results need to be sorted vertically in alphabetical order.
Any suggestion would be greatly appreciated.
Thanks
John
You may want to try the following:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">
<xsl:template match="/">
<html>
<body>
<h1>Collection</h1>
<table border="1" style="display:inline-block">
<tr>
<th>Title</th>
<th>Artist</th>
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:variable name="sorted-cds">
<xsl:for-each select="catalog/cd">
<xsl:sort select="title" order="ascending" data-type="text" />
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="n" select="ceiling(count(catalog/cd) div 2)"/>
<xsl:for-each select="exsl:node-set($sorted-cds)/cd[position() <= $n]">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<td><xsl:value-of select="following-sibling::cd[$n]/title"/></td>
<td><xsl:value-of select="following-sibling::cd[$n]/artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The basic idea is to sort the CDs as node set (sorted-cds)
calculate the half of number of rows (n) and and then iterate over
the first half of the collection (position() <= $n).
In order to get the corresponding second CD in the same row, just
skip (following-sibling::) $n CDs in the collection.
(Note that you need to include the common EXSL extensions xmlns:exsl...
because the non-standard exsl:node-set function is used.)
Another note: If you want to try out the above in the page
you linked in your question, you may need to replace the <=
by &lt;=; they seem to have a quoting bug there(?).

Extract property with xslt

I have the following xml content in a file:
<testsuite errors="1" failures="1" name="unittest.suite.TestSuite" tests="3" time="6.540">
<properties>
<property name="comp1" value="0.0.0.0:80=0.0.1"/>
<property name="comp2" value="12.34.56.78:80=0.0.1"/>
and I want to create a table like
Name Value
comp1 0.0.0.0:80=0.0.1
comp2 12.34.56.78:80=0.0.1
with an xsl. I tried the following
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th>Name</th>
<th>Value</th>
</tr>
<xsl:for-each select="testsuite/properties/property">
<tr>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="value"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
which just gives an empty table. How to do this correctly? I only found examples on the internet which were way to complex. If someone knows a good tutorial on such things, I am welcome as well.
# is used for attributes, if you don't use then it will be by default treated as an element..
so your code works fine if the XML is like this:
<testsuite errors="1" failures="1" name="unittest.suite.TestSuite" tests="3" time="6.540">
<properties>
<property>
<name>comp1</name>
<value>0.0.0.0:80=0.0.1</value>
</property>
<property>
<name>comp2</name>
<value>12.34.56.78:80=0.0.1</value>
</property>
..........
........
And here is your corrected code, observe the usage of #
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table border="1">
<tr bgcolor="#9acd32">
<th>Name</th>
<th>Value</th>
</tr>
<xsl:for-each select="testsuite/properties/property">
<tr>
<td><xsl:value-of select="#name"/></td>
<td><xsl:value-of select="#value"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Try
<td><xsl:value-of select="#name"/></td>
<td><xsl:value-of select="#value"/></td>
When accessing an attribute you need # before the name.