需要什么 XSLT 来提取和转换这个特定的 XHTML?

问题描述 投票:0回答:1

我正在尝试从较大的文件中提取某些 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 xml xslt
1个回答
0
投票

假设 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。

© www.soinside.com 2019 - 2024. All rights reserved.