我正在尝试使用XSL将XML文档转换为HTML页面。我有95%的路,但我遇到了包含文本和其他节点必须按顺序显示的节点的问题。XSL XPath按顺序在每个循环中选择混合文本和节点?
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>
,和<cvc></cvc>
的混合物。在这个级别之后永远不会嵌套,即<b></b>
将只包含文本。
这是我想要的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 <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>
我已经尝试了不同的XPath功能,for-each
循环,两者的混合物,但我无法弄清楚如何得到我想要的输出。我已经得到的最接近的是这个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: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>
但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 , consectetur adipiscing elit.
Maecenas sed pretium nunc.
Proin tincidunt sapien dolor, posuere varius dui efficitur ac.
<strong>dolor sit amet</strong><a href="#">foo/bar/qux</a><a href="#">http://google.com/</a>
</p>
<p>
Foo bar , foo adipiscing elit.
Maecenas sed pretium nunc.
Proin tincidunt sapien dolor, posuere varius dui efficitur ac.
<strong>doqux amet</strong><a href="#">foo/bar/qux</a><a href="#">http://google.com/</a>
</p>
</body>
</html>
你需要学习如何使用模板规则。使用模板规则对XML树进行递归处理是使用XSLT的自然方式,对于处理混合内容特别重要。 –