How can I use <xsl:template match=""> to match the author - html

I'm trying to generate an HTML file using XML and XSL (XSLT). I want to show all the books that have been written by certain author (EX "Mario Vargas Llosa"). How can I do that using the match attribute in xsl:template?
XML CODE:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="template.xsl" type="text/xsl" ?>
<library>
<book>
<title language="es">La vida está en otra parte</title>
<author>Milan Kundera</author>
<publishDate year="1973"/>
</book>
<book>
<title language="es">Pantaleón y las visitadoras</title>
<author>Mario Vargas Llosa</author>
<publishDate year="1973"/>
</book>
<book>
<title language="es">Conversación en la catedral</title>
<author>Mario Vargas Llosa</author>
<publishDate year="1969"/>
</book>
<book>
<title language="en">Poems</title>
<author>Edgar Allan Poe</author>
<publishDate year="1890"/>
</book>
<book>
<title language="fr">Les Miserables</title>
<author>Victor Hugo</author>
<publishDate year="1862"/>
</book>
<book>
<title language="es">Plenilunio</title>
<author>Antonio Muñoz Molina</author>
<publishDate year="1997"/>
</book>
</library>
XSLT CODE:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<xsl:for-each select="library/book">
<h1>Title:
<xsl:value-of select="title"/>
</h1>
<p>
<strong>Author: </strong>
<xsl:value-of select="author"/>
</p>
<p>
<strong>Publishing date: </strong>
<xsl:value-of select="publishDate/#year"/>
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
Thanks in advance.

Change your XSLT file to
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<xsl:for-each select="library/book[author='Mario Vargas Llosa']">
<h1>Title:
<xsl:value-of select="title"/>
</h1>
<p>
<strong>Author: </strong>
<xsl:value-of select="author"/>
</p>
<p>
<strong>Publishing date: </strong>
<xsl:value-of select="publishDate/#year"/>
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
and your xsl:for-each will iterate over all <book>s of "Mario Vargas Llosa". So the output (in your browser) will be

One line modification in XSLT. You need to add a predicate.
<xsl:for-each select="library/book[author='Mario Vargas Llosa']">

Related

XSLT How to print all attributes inside an element: <node id="" name="" random=""></node>

The only answers I come across is how to list the value of the node and child nodes itself. What I would like to know is how I can print all the values inside the node tag itself.
XML (there can be more books within catalog)
<data>
<info>
<catalog Id="1111" Locale="en_GB">
<books>
<book id="01" Name="Title 1" Author="John Doe"></book>
<book id="02" Name="Title 2" Author="Jane Doe"></book>
</books>
What I currently have:
<?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>
<xsl:for-each select="data/info/catalog">
<xsl:value-of select="#Id" />
<xsl:value-of select="/books/book/#Name"/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Specifically, I would like the output to be:
Catalog Id: 1111
Attributes:
id: 01
Name: Title 1
Author: John Doe
id: 02
Name: Title 2
Author: Jane Doe
The reason it's being done this way because I have dozens upon dozens of values and it's easier to fit them inside the node tag itself instead of creating hundreds of sub-sub-subchilds.
You did not post the exact HTML code you want to have. Try something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/data">
<html>
<body>
<xsl:for-each select="info/catalog">
<xsl:text>Catalog Id: </xsl:text>
<xsl:value-of select="#Id" />
<br/>
<br/>
<xsl:text>Attributes:</xsl:text>
<br/>
<xsl:for-each select="books/book">
<xsl:for-each select="#*">
<xsl:value-of select="name()" />
<xsl:text>: </xsl:text>
<xsl:value-of select="." />
<br/>
</xsl:for-each>
<br/>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Capitalize all text inside of <title> tags for a group of html files in side a single folder

I'm currently using this code: (Linux Bash)
for x in *.html; do sed -i "a/(sudo grep -o '<title>.*</title>' $x)(sudo grep -o '<title>.*</title>' | sudo sed "s/\b[a-z]/\u&/g")//g" $x; echo moving $x; done
and it wont seem to be working, can anyone help me out, do I have to keep using (sed) or try using other plugins?
INTRO:
I have a like thousand html FILES all of them have tags inside but the text between the tags are all lower case,
I want to capitalize first letters for each word between tags, and do it all at once using loop in bash command.
EXAMPLE:
<title>sample title</title>
TO >>>
<title>Sample Title</title>
You can use the following XSLT stylesheet to solve your issue:
INPUT FILES:
$ more ?.html
::::::::::::::
1.html
::::::::::::::
<!DOCTYPE html>
<html>
<head>
<title>title reference 1.html</title>
</head>
<body>
The content of the document......
</body>
</html>
::::::::::::::
2.html
::::::::::::::
<!DOCTYPE html>
<html>
<head>
<title>title reference 2.html</title>
</head>
<body>
The content of the document......
</body>
</html>
STYLESHEET:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:redirect="http://xml.apache.org/xalan/redirect" extension-element-prefixes="redirect" xmlns:xalan="http://xml.apache.org/xslt" exclude-result-prefixes="xalan redirect ">
<xsl:output method="html" indent="yes" xalan:indent-amount="4" include-content-type="false" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="node() | #*">
<xsl:copy>
<xsl:apply-templates select="node() | #*"/>
</xsl:copy>
</xsl:template>
<xsl:template name="TitleCase">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text,' ')">
<xsl:call-template name="TitleCaseWord">
<xsl:with-param name="text" select="substring-before($text,' ')"/>
</xsl:call-template>
<xsl:text> </xsl:text>
<xsl:call-template name="TitleCase">
<xsl:with-param name="text" select="substring-after($text,' ')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="TitleCaseWord">
<xsl:with-param name="text" select="$text"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="TitleCaseWord">
<xsl:param name="text"/>
<xsl:value-of select="translate(substring($text,1,1),'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')" /><xsl:value-of select="substring($text,2,string-length($text)-1)" />
</xsl:template>
<xsl:template match="//*[local-name()='title']">
<title>
<xsl:call-template name="TitleCase">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</title>
</xsl:template>
</xsl:stylesheet>
CMD:
$ for i in *.html; do java -classpath "./tagsoup-1.2.jar:./saxon9he.jar" net.sf.saxon.Transform --suppressXsltNamespaceCheck:on -x:org.ccil.cowan.tagsoup.Parser -s:1.html -xsl:title_upper.xsl -o:"new_${i}"; done
You can download the 2 jars at
https://mvnrepository.com/artifact/org.ccil.cowan.tagsoup/tagsoup/1.2
and http://saxon.sourceforge.net/
OUTPUT:
$ more new_*
::::::::::::::
new_1.html
::::::::::::::
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml">
<head>
<title xmlns="">Title Reference 1.html</title>
</head>
<body>
The content of the document......
</body>
</html>
::::::::::::::
new_2.html
::::::::::::::
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml">
<head>
<title xmlns="">Title Reference 1.html</title>
</head>
<body>
The content of the document......
</body>
</html>
If you have issue with saxon you can just use xsltproc as I use a version 1.0 stylesheet:
for i in *.html; do xsltproc --html title_upper.xsl ${i} > "new_${i}"; done

Merging two XML files while transforming them using XSL

I have two XML files which I want to transform into one HTML file using XSL.
I transform them using xsltproc first.xml transform.xsl > output.html command in Linux terminal. Values from first.xml work perfectly and transform into HTML but I cannot force second.xml to work as well. It just didn't appear in file. I know there were questions like this on StackOverflow but I still couldn't figure out what I am doing wrong. It seems like something is wrong with match = "document('effects.xml')/effects" but I don't know what exactly.
first.xml
<elements>
<listOfElements>
<element>
*some data*
</element>
<element>
*some data*
</element>
</listOfElements>
</elements>
second.xml
<effects>
<effect>
<name> NAME1 </name>
<cost> COST1 </cost>
</effect>
<effect>
<name> NAME2 </name>
<cost> COST2 </cost>
</effect>
<effect>
<name> NAME3 </name>
<cost> COST3 </cost>
</effect>
</effect>
transform.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:text disable-output-escaping='yes'><!DOCTYPE html></xsl:text>
<html>
<head>
<meta charset="UTF-8"/>
<link rel="stylesheet" type="text/css" href="styl.css"/>
</head>
<body>
<xsl:apply-templates select="elements"/>
<xsl:apply-templates select="effects"/>
</body>
</html>
</xsl:template>
<xsl:template match="elements">
<div>
THIS WORKS
</div>
</xsl:template>
<xsl:template match="document('effects.xml')/effects">
<div>
<xsl:for-each select="effects/effect">
<div>
<p><xsl:value-of select="name"/></p>
</div>
</xsl:for-each>
</div>
</xsl:template>
Use <xsl:apply-templates select="document('effects.xml')/effects"/> and then in the match="effects" and <xsl:for-each select="effect">.

how to list item in dropdown based on another dropdown using xml file?

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" intent="yes"/>
<xsl:template match="/">
<xsl:template match="/">
<html>
<body>
<center>
<select id='bookID' onchange='getInputs(this.value)'>
<xsl:for-each select="BookDetail/book" >
<option><xsl:value-of select="bookName"/></option>
</xsl:for-each>
</select>
<select id="bookLink">
<xsl:for-each select="BookDetail">
<option><xsl:value-of select="link"/> </option>
</xsl:for-each>
</select>
</center>
</body>
</html>
</xsl:template>
</xsl:template>
</xsl:stylesheet>
I have created an XML file where the details of book is stored.
There are two dropdowns 1) BookName 2 )BookLink
Now I want is to change dropdown list of BookLink when any book name is selected from the dropdown.
XML File is as below:
<BookDetail>
<book>
<bookName>Dollar Bahu</bookName>
<link>http:\\DollarBahu.in</link>
</book>
<book>
<bookName>The Lost Symbol</bookName>
<link>http:\\TheLostSymbol.in</link>
</book>
<book>
<bookName>Keep The Change</bookName>
<link>http:\\KeepTheChange.in</link>
</book>
</BookDetail>

Dynamically change value of in an XSL file

Currently the displaying the XML in a browser along with the XSL data is correct except for one thing. In some colleges I have one department while in orders I have more than one (up to 9). How I can dynamically output the data based on the number of department for each college? Currently it only outputs one department per college.
College.xml File
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="colleges.xsl"?><colleges>
<college id="0">
<school>College of Education</school>
<mission>text</mission>
<department id="0">Educational Psychology and Leadership</department>
<department id="1">Health and Human Performance</department>
<department id="2">Language, Literacy and Intercultural Studies</department>
<department id="3">Teaching, Learning and Innovation</department>
</college>
<college id="1">
<school>College of Nursing</school>
<mission>text</mission>
<department id="0">Nursing</department>
</college>
<college id="2">
<school>School of Business</school>
<mission>text</mission>
<department id="0">Accounting and Management Information Systems</department>
<department id="1">Applied Business Technology</department>
</college></colleges>
College.xsl file:
<?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 style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="colleges/college">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"><xsl:value-of select="school"/></span> - <br /><xsl:value-of select="mission"/>
</div>
<div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
<p>
<xsl:value-of select="department"/><br />
</p>
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Try:
<xsl:template match="/"> ...
<xsl:for-each select="colleges/college">
...
<xsl:apply-templates select="department"/>
...
</xsl:for-each>
</xsl:template>
<xsl:template match="department">... what you want for each department</xsl:template>
Give this a shot...
<xsl:template match="/">
<html>
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="colleges/college">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"><xsl:value-of select="school"/></span> - <br /><xsl:value-of select="mission"/>
</div>
<div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
<p>
<xsl:apply-templates select="department"/>
</p>
</div>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="department">
<xsl:value-of select="."/><br />
</xsl:template>