gpt4 book ai didi

html - XSLT:将分组的 html 元素移动到节级别

转载 作者:太空狗 更新时间:2023-10-29 14:48:09 25 4
gpt4 key购买 nike

我正在尝试编写一个 XSLT,它根据 header 级别将 HTML 文件组织成不同的部分级别。这是我的输入:

<html>
<head>
<title></title>
</head>
<body>
<h1>HEADER 1 CONTENT</h1>
<p>Level 1 para</p>
<p>Level 1 para</p>
<p>Level 1 para</p>
<p>Level 1 para</p>

<h2>Header 2 CONTENT</h2>
<p>Level 2 para</p>
<p>Level 2 para</p>
<p>Level 2 para</p>
<p>Level 2 para</p>
</body>
</html>

目前我正在使用一个相当简单的结构,因此该模式将暂时保持不变。我需要这样的输出...

<document> 
<section level="1">
<header1>Header 1 CONTENT</header1>
<p>Level 1 para</p>
<p>Level 1 para</p>
<p>Level 1 para</p>
<p>Level 1 para</p>
<section level="2">
<header2>Header 2 CONTENT</header2>
<p>Level 2 para</p>
<p>Level 2 para</p>
<p>Level 2 para</p>
<p>Level 2 para</p>
</section>
</section>
</document>

我一直在处理这个例子:Stackoverflow Answer

但是,我无法让它完全按照我的需要去做。

我正在使用 Saxon 9 在 Oxygen 中运行 xslt for dev。我将在生产中使用 cmd/bat 文件。仍然是 Saxon 9。如果可能,我想处理最多 4 个嵌套部分级别。

非常感谢任何帮助!

我需要附加到此,因为我遇到了另一个规定。我可能早该想到这一点。

我遇到了以下代码示例

<html>
<head>
<title></title>
</head>
<body>
<p>Level 1 para</p>
<p>Level 1 para</p>
<p>Level 1 para</p>
<p>Level 1 para</p>

<h1>Header 2 CONTENT</h1>
<p>Level 2 para</p>
<p>Level 2 para</p>
<p>Level 2 para</p>
<p>Level 2 para</p>
</body>
</html>

如您所见,<p><body> 的 child 在我的第一个片段中,<p>始终是 header 级别的子级。我想要的结果与上面相同,只是当我遇到 <p> 时作为 <body> 的 child , 它应该包裹在 <section level="1"> 中.

<document> 
<section level="1">
<p>Level 1 para</p>
<p>Level 1 para</p>
<p>Level 1 para</p>
<p>Level 1 para</p>
</section>
<section level="1">
<header1>Header 2 CONTENT</header1>
<p>Level 2 para</p>
<p>Level 2 para</p>
<p>Level 2 para</p>
<p>Level 2 para</p>
</section>
</document>

最佳答案

这是一个 XSLT 2.0 样式表:

<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">

<xsl:output indent="yes"/>

<xsl:function name="mf:group" as="node()*">
<xsl:param name="elements" as="element()*"/>
<xsl:param name="level" as="xs:integer"/>
<xsl:for-each-group select="$elements" group-starting-with="*[local-name() eq concat('h', $level)]">
<xsl:choose>
<xsl:when test="self::*[local-name() eq concat('h', $level)]">
<section level="{$level}">
<xsl:element name="header{$level}"><xsl:apply-templates/></xsl:element>
<xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
</section>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:function>

<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="/html">
<document>
<xsl:apply-templates select="body"/>
</document>
</xsl:template>

<xsl:template match="body">
<xsl:sequence select="mf:group(*, 1)"/>
</xsl:template>

</xsl:stylesheet>

它应该按照您的要求执行,尽管它不会停止在四个嵌套级别,而是只要找到 h[n] 元素就会分组。

关于html - XSLT:将分组的 html 元素移动到节级别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4547271/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com