无法将模板应用于子元素
Can't apply template to child element
我有一个 XML 文件,其中包含嵌套在 <p>
元素内的另一个元素中的子元素。我的 XSLT 很好地提取了 <p>
元素,但它忽略了 <span>
。我知道它与 xPath 有关,但我不知道如何使用此 XSLT 结构来完成它。
<newsItem>
<inlineXml>
<h2>Calendar</h2>
<p><strong><span class="dates">June 16-18:</span>National Conference, Denver</strong></p>
<p><strong><span class="dates">June 19-21:</span>Local Event, Chicago</strong></p>
<inlineXml>
</newsItem>
这是我的 XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="newsItem">
<newsItem><xsl:apply-templates/></newsItem>
</xsl:template>
<xsl:template match="h2">
<h2><xsl:value-of select="normalize-space(.)"/></h2>
</xsl:template>
<xsl:template match="p/strong/span">
<date><xsl:value-of select="."/></date>
</xsl:template>
<xsl:template match="p">
<p><xsl:value-of select="normalize-space(.)"/></p>
</xsl:template>
</xsl:stylesheet>
这是想要的结果:
<newsItem>
<inlineXml>
<h2>Calendar</h2>
<p><date>June 16-18:</date>National Conference, Denver</p>
<p><date>June 19-21:</date>Local Event, Chicago</p>
<inlineXml>
</newsItem>
这可能很简单,但它难倒了我。
谢谢
如果你改变:
<xsl:template match="p">
<p><xsl:value-of select="normalize-space(.)"/></p>
</xsl:template>
至:
<xsl:template match="p">
<p><xsl:apply-templates/></p>
</xsl:template>
你的结果将变成:
<?xml version="1.0"?>
<newsItem>
<h2>Calendar</h2>
<p><date>June 16-18:</date>National Conference, Denver</p>
<p><date>June 19-21:</date>Local Event, Chicago</p>
</newsItem>
这与预期结果非常接近,只是缺少 <inlineXml>
包装器。这是因为没有与之匹配的模板,所以如果你添加:
<xsl:template match="inlineXml">
<inlineXml><xsl:apply-templates/></inlineXml>
</xsl:template>
你会得到你想要的结果。
请注意,现在您拥有三个非常相似的模板:
<xsl:template match="newsItem">
<newsItem><xsl:apply-templates/></newsItem>
</xsl:template>
<xsl:template match="p">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="inlineXml">
<inlineXml><xsl:apply-templates/></inlineXml>
</xsl:template>
可以合二为一:
<xsl:template match="newsItem | inlineXml | p">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
此 XSLT 1.0 样式表 ...
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" version="5" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<html>
<head>
<title>Inline XML</title>
</head>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="strong[span/@class='dates']">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="strong/span[@class='dates']">
<date>
<xsl:apply-templates />
</date>
</xsl:template>
</xsl:stylesheet>
... 将转换此输入文档 ...
<newsItem>
<inlineXml>
<h2>Calendar</h2>
<p><strong><span class="dates">June 16-18:</span>National Conference, Denver</strong></p>
<p><strong><span class="dates">June 19-21:</span>Local Event, Chicago</strong></p>
</inlineXml>
</newsItem>
... 进入此输出 html 页 ...
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Inline XML</title>
</head>
<body>
<newsItem>
<inlineXml>
<h2>Calendar</h2>
<p>
<date>June 16-18:</date>National Conference, Denver
</p>
<p>
<date>June 19-21:</date>Local Event, Chicago
</p>
</inlineXml>
</newsItem>
</body>
</html>
一些建议
- 没有理由受限于 XSLT 1.0,您可以
升级到 XSLT 2.0,甚至在浏览器平台上(由 Saxon 提供
CE).
- 如果您的
date
元素是一种微格式,
你应该考虑 html 5 element time
.
我有一个 XML 文件,其中包含嵌套在 <p>
元素内的另一个元素中的子元素。我的 XSLT 很好地提取了 <p>
元素,但它忽略了 <span>
。我知道它与 xPath 有关,但我不知道如何使用此 XSLT 结构来完成它。
<newsItem>
<inlineXml>
<h2>Calendar</h2>
<p><strong><span class="dates">June 16-18:</span>National Conference, Denver</strong></p>
<p><strong><span class="dates">June 19-21:</span>Local Event, Chicago</strong></p>
<inlineXml>
</newsItem>
这是我的 XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="newsItem">
<newsItem><xsl:apply-templates/></newsItem>
</xsl:template>
<xsl:template match="h2">
<h2><xsl:value-of select="normalize-space(.)"/></h2>
</xsl:template>
<xsl:template match="p/strong/span">
<date><xsl:value-of select="."/></date>
</xsl:template>
<xsl:template match="p">
<p><xsl:value-of select="normalize-space(.)"/></p>
</xsl:template>
</xsl:stylesheet>
这是想要的结果:
<newsItem>
<inlineXml>
<h2>Calendar</h2>
<p><date>June 16-18:</date>National Conference, Denver</p>
<p><date>June 19-21:</date>Local Event, Chicago</p>
<inlineXml>
</newsItem>
这可能很简单,但它难倒了我。
谢谢
如果你改变:
<xsl:template match="p">
<p><xsl:value-of select="normalize-space(.)"/></p>
</xsl:template>
至:
<xsl:template match="p">
<p><xsl:apply-templates/></p>
</xsl:template>
你的结果将变成:
<?xml version="1.0"?>
<newsItem>
<h2>Calendar</h2>
<p><date>June 16-18:</date>National Conference, Denver</p>
<p><date>June 19-21:</date>Local Event, Chicago</p>
</newsItem>
这与预期结果非常接近,只是缺少 <inlineXml>
包装器。这是因为没有与之匹配的模板,所以如果你添加:
<xsl:template match="inlineXml">
<inlineXml><xsl:apply-templates/></inlineXml>
</xsl:template>
你会得到你想要的结果。
请注意,现在您拥有三个非常相似的模板:
<xsl:template match="newsItem">
<newsItem><xsl:apply-templates/></newsItem>
</xsl:template>
<xsl:template match="p">
<p><xsl:apply-templates/></p>
</xsl:template>
<xsl:template match="inlineXml">
<inlineXml><xsl:apply-templates/></inlineXml>
</xsl:template>
可以合二为一:
<xsl:template match="newsItem | inlineXml | p">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
此 XSLT 1.0 样式表 ...
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="html" version="5" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<html>
<head>
<title>Inline XML</title>
</head>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="strong[span/@class='dates']">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="strong/span[@class='dates']">
<date>
<xsl:apply-templates />
</date>
</xsl:template>
</xsl:stylesheet>
... 将转换此输入文档 ...
<newsItem>
<inlineXml>
<h2>Calendar</h2>
<p><strong><span class="dates">June 16-18:</span>National Conference, Denver</strong></p>
<p><strong><span class="dates">June 19-21:</span>Local Event, Chicago</strong></p>
</inlineXml>
</newsItem>
... 进入此输出 html 页 ...
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Inline XML</title>
</head>
<body>
<newsItem>
<inlineXml>
<h2>Calendar</h2>
<p>
<date>June 16-18:</date>National Conference, Denver
</p>
<p>
<date>June 19-21:</date>Local Event, Chicago
</p>
</inlineXml>
</newsItem>
</body>
</html>
一些建议
- 没有理由受限于 XSLT 1.0,您可以 升级到 XSLT 2.0,甚至在浏览器平台上(由 Saxon 提供 CE).
- 如果您的
date
元素是一种微格式, 你应该考虑 html 5 elementtime
.