我正在尝试使用XSL将XML文档转换为HTML页面。我有95%的方式,但我遇到的问题是包含文本和其他节点的节点必须按顺序显示。
XML:
<chapter title="Chapter 1" reqlen="2500">
<section title="The Quick Brown Fox">
<subsection title="null">
<keywords>foo,bar</keywords>
<body>
<p>
Lorem ipsum <b>dolor sit amet</b>, consectetur adipiscing elit.
Maecenas sed pretium nunc.
<int>foo/bar/qux</int>
Proin tincidunt sapien dolor, posuere varius dui efficitur ac.
<ext>http://google.com/</ext>
</p>
<p>
Foo bar <b>doqux amet</b>, foo adipiscing elit.
Maecenas sed pretium nunc.
<int>foo/bar/qux</int>
Proin tincidunt sapien dolor, posuere varius dui efficitur ac.
<ext>http://google.com/</ext>
</p>
</body>
<note>Lorem ipsum</note>
</subsection>
</section>
</chapter>
XSL:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="stylesheet" version="1.0">
<xsl:template match="xsl:stylesheet" />
<xsl:template match="/chapter">
<html>
<head>
<title>
<xsl:value-of select="@title" />
</title>
<style type="text/css">body {
padding: 50px 10%;
}</style>
</head>
<body>
<h1>
<xsl:value-of select="@title" />
</h1>
<xsl:for-each select="section">
<xsl:if test="@title!='null'">
<h2>
<xsl:value-of select="@title" />
</h2>
</xsl:if>
<xsl:for-each select="subsection">
<xsl:if test="@title!='null'">
<h3>
<xsl:value-of select="@title" />
</h3>
</xsl:if>
<xsl:for-each select="body/p">
<p>
<xsl:value-of select="current()" />
</p>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
这导致以下HTML:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Chapter 1</title>
<style type="text/css">
body {
padding: 50px 10%;
}
</style>
</head>
<body>
<h1>Chapter 1</h1>
<h2>The Quick Brown Fox</h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Maecenas sed pretium nunc.
foo/bar/qux
Proin tincidunt sapien dolor, posuere varius dui efficitur ac.
http://google.com/
</p>
<p>
Foo bar doqux amet, foo adipiscing elit.
Maecenas sed pretium nunc.
foo/bar/qux
Proin tincidunt sapien dolor, posuere varius dui efficitur ac.
http://google.com/
</p>
</body>
</html>
问题是,我正在尝试转换<p></p>
个节点内的某些标签。
在<p>
个节点内,可以混合使用纯文本和节点<b></b>
,<i></i>
,<int></int>
,<ext></ext>
和{{ 1}}。永远不会嵌套超出此级别,即<cvc></cvc>
只会包含文本。
这是我想要的HTML:
<b></b>
我尝试了不同的XPath函数,<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Chapter 1</title>
<style type="text/css">
body {
padding: 50px 10%;
}
</style>
</head>
<body>
<h1>Chapter 1</h1>
<h2>The Quick Brown Fox</h2>
<p>
Lorem ipsum <strong>dolor sit amet</strong>, consectetur adipiscing elit.
Maecenas sed pretium nunc.
<a href="/foo/bar/qux">foo/bar/qux</a>
Proin tincidunt sapien dolor, posuere varius dui efficitur ac.
<a href="http://google.com/">http://google.com/</a>
</p>
<p>Foo bar <strong>doqux amet</strong>, foo adipiscing elit.
Maecenas sed pretium nunc.
<a href="/foo/bar/qux">foo/bar/qux</a>
Proin tincidunt sapien dolor, posuere varius dui efficitur ac.
<a href="http://google.com/">http://google.com/</a>
</p>
</body>
</html>
循环以及两者的混合,但我无法弄清楚如何获得我想要的输出。我最接近的是这个XSL:
for-each
但HTML输出乱序:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" id="stylesheet" version="1.0">
<xsl:template match="xsl:stylesheet" />
<xsl:template match="/chapter">
<html>
<head>
<title>
<xsl:value-of select="@title" />
</title>
<style type="text/css">body {
padding: 50px 10%;
}</style>
</head>
<body>
<h1>
<xsl:value-of select="@title" />
</h1>
<xsl:for-each select="section">
<xsl:if test="@title!='null'">
<h2>
<xsl:value-of select="@title" />
</h2>
</xsl:if>
<xsl:for-each select="subsection">
<xsl:if test="@title!='null'">
<h3>
<xsl:value-of select="@title" />
</h3>
</xsl:if>
<xsl:for-each select="body/p">
<p>
<xsl:for-each select="text()">
<xsl:value-of select="current()" />
</xsl:for-each>
<xsl:for-each select="b">
<strong>
<xsl:value-of select="current()" />
</strong>
</xsl:for-each>
<xsl:for-each select="int">
<a href="#">
<xsl:value-of select="current()" />
</a>
</xsl:for-each>
<xsl:for-each select="ext">
<a href="#">
<xsl:value-of select="current()" />
</a>
</xsl:for-each>
</p>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
考虑这样的事情:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="xsl:stylesheet" />
<xsl:template match="/chapter">
<html>
<head>
<title>
<xsl:value-of select="@title" />
</title>
<style type="text/css">
body {
padding: 50px 10%;
}
</style>
</head>
<body>
<h1>
<xsl:value-of select="@title" />
</h1>
<xsl:for-each select="section">
<xsl:if test="@title!='null'">
<h2>
<xsl:value-of select="@title" />
</h2>
</xsl:if>
<xsl:for-each select="subsection">
<xsl:if test="@title!='null'">
<h3>
<xsl:value-of select="@title" />
</h3>
</xsl:if>
<xsl:for-each select="body/p">
<p>
<xsl:apply-templates/>
</p>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="b">
<strong>
<xsl:value-of select="."/>
</strong>
</xsl:template>
<xsl:template match="int">
<a href="#">
<xsl:value-of select="."/>
</a>
</xsl:template>
<xsl:template match="ext">
<a href="#">
<xsl:value-of select="."/>
</a>
</xsl:template>
</xsl:stylesheet>