我正在尝试从较大的文件中提取某些 HTML 的子集,然后对结果执行一些转换。我已经取得了一些进展,但我还缺少一两部分来使这项工作按预期进行。
这是我想要转换的 XHTML 的一个大大简化的版本:
<html>
<head>
<!-- lots of stuff I don't care about -->
</head>
<body>
<div>
<!-- lots of stuff I don't care about -->
<div>
<!-- lots of stuff I don't care about -->
<div id="key_div">
<div id="ignore_this">
<!-- lots of stuff I don't care about -->
</div>
<p>More junk I don't want</p>
<p>Even more junk I don't want</p>
<h2><span class="someClass" id="someID">Header</span></h2>
<p>Stuff I want to keep</p>
<!-- A lot of stuff I want to keep -->
<p>More stuff I want to keep</p>
<ul>
<li><a href="/some/old/path">Fun Place</a></li>
<li><a href="/some/old/other">Better Place</a></li>
</ul>
</div>
<!-- lots of stuff I don't care about -->
</div>
<!-- lots of stuff I don't care about -->
</div>
</body>
</html>
我想从
<h2>
标签中提取所有内容,通过 <div>
内的其余内容以及 id
的 "key_div"
。但我还想将 <h2>
转换为更简单的 <h1>
,并且我需要修改列表中的 href
。最终结果应该是这样的:
<html>
<head>
<!-- My own header stuff -->
</head>
<body>
<h1>Header</h1>
<p>Stuff I want to keep</p>
<!-- A lot of stuff I want to keep -->
<p>More stuff I want to keep</p>
<ul>
<li><a href="/new/path">Fun Place</a></li>
<li><a href="/new/other">Better Place</a></li>
</ul>
</body>
</html>
通过使用以下 XSL,我能够完成大部分基本提取,而无需进行任何所需的转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="x">
<xsl:output indent="yes" encoding="utf-8"/>
<xsl:template match="/">
<html>
<head>
<title>My Title</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="div[@id='key_div']/*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="div[@id='ignore_this']"/>
<xsl:template match="text()"/>
</xsl:stylesheet>
这会导致:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>My Title</title>
</head>
<body>
<p>More junk I don't want</p>
<p>Even more junk I don't want</p>
<h2><span class="someClass" id="someID">Header</span></h2>
<p>Stuff I want to keep</p>
<p>More stuff I want to keep</p>
<ul>
<li><a href="/some/old/path">Fun Place</a></li>
<li><a href="/some/old/other">Better Place</a></li>
</ul>
</body>
</html>
我不知道如何去除
<h2>
之前的东西。
我不知道如何将
<h2><span class="someClass" id="someID">Header</span></h2>
转换为 <h1>Header</h1>
或如何转换 href
。我将转换与提取相结合的所有尝试通常都以没有内容告终。
我还需要执行一些其他转换,但现在我将重点关注这个示例以帮助我开始。我提到它是为了任何可能的答案不会阻止任何其他可能的转换。
假设 HTML 输入元素不在命名空间中(就像在您的示例中一样,尽管您谈论的是 XHTML),它足以使用身份转换以及正文、h2、h2/span 和 href 属性的模板:
<xsl:template match="body">
<xsl:copy>
<xsl:apply-templates select=".//div[@id = 'key_div']/h2/(., following-sibling::node())"/>
</xsl:copy>
</xsl:template>
<xsl:template match="h2">
<h1>
<xsl:apply-templates/>
</h1>
</xsl:template>
<xsl:template match="h2/span">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="ul/li/a/@href">
<xsl:attribute name="{node-name()}" select="replace(., '/some/old', '/new')"/>
</xsl:template>
在某些地方使用XSLT 2/3、XPath 2/3。