I have not practiced XML in over a year. My question is, using the samples below, why my for-each statement is only printing the first paragraph.
If you are wanting to know why my XML is using standard HTML "p" tags that I am trying to put back into "p" tags in my XSL file: the reason is I am batch processing several long writer documents from a word processor into HTML files. There are thousands (maybe tens of thousands) of paragraph tags. I cannot output XML files in any format I can use or manipulate the way I want.
I can however save the HTML file with an XML extension and work with that. I have already converted a few other files, but not tried to for-each the
tags yet.
My XML file
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="example.xsl"?>
<Library>
<Books>
<MyBooks>
<my_favorite_book>
<title>the title of my favorite book</title>
<p>paragraph 1</p>
<p>paragraph 2</p>
<p>paragraph 3</p>
<p>paragraph 4</p>
<p>paragraph 5</p>
<p>paragraph 6</p>
<p>paragraph 7</p>
<p>paragraph 8</p>
<p>paragraph 9</p>
</my_favorite_book>
</MyBooks>
</Books>
</Library>
My XSL file
<?xml version="1.0"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<body>
<p align="center">
<span style="font-size: 5em;">
<b>
<xsl:value-of select="Library/Books/MyBooks/my_favorite_book/title" />
</b>
</span>
<br/>
</p>
<xsl:for-each select="Library/Books/MyBooks/my_favorite_book">
<p>
<xsl:value-of select="p" />
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The Web browser output (FireFox 54.0.1 (32-bit))
My question is, using the samples below, why my for-each statement is only printing the first paragraph.
Because your for-each
,
<xsl:for-each select="Library/Books/MyBooks/my_favorite_book">
is selecting the only my_favorite_book
, and your xsl:value-of
,
<xsl:value-of select="p" />
is selecting all of my_favority_book
's children only to take the string value of the first such p
,
paragraph 1
The shortest fix to your program would be to loop over the paragraphs,
<xsl:for-each select="Library/Books/MyBooks/my_favorite_book/p">
and take the value-of each,
<xsl:value-of select="." />
or, instead of looping with xsl:for-each
, you might use apply-templates
instead:
<xsl:apply-templates select="Library/Books/MyBooks/my_favorite_book/p">
if you come to have further pattern matching to do, or copy-of
if you don't:
<xsl:copy-of select="Library/Books/MyBooks/my_favorite_book/p">
I discovered the answer in another Stack Overflow post that worked.
That is, to change the above code to the code below:
<xsl:for-each select="Library/Books/MyBooks/my_favorite_book/p">
<p>
<xsl:value-of select="." />
</p>
</xsl:for-each>
Also, while looking at some other projects I did, and reading other posts here, I now recall that using the "template" methods yielded a smoother and more flexible result, so I am going to radically modify my XSL file tomorrow and leave an update here.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.