for-each-group 文本段落 - xslt 2.0

for-each-group text paragraph - xslt 2.0

我正在寻找一种基于标题 h1 对文本进行分组的解决方案。我用 for-each-group、starts-with ="h1" 试过了。问题是 h1 与其余元素不在同一级别 (div/h1)。

输入html:

<!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>test</title>   
</head>
<body>
<div>
    <h1><b>TRAIN</b></h1>
</div>
<p>text</p>
<p>In this field there is text</p>
<div>
    <h1><b>nr1</b><b>CAR</b></h1>
</div>
<h2><b>1.</b><b>nr2</b><b>area</b></h2>
<p>infos about cars</p>
<p><b>more and</b>more infos about cars</p>
</body>
</html>

我目前拥有的是:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
xpath-default-namespace="http://www.w3.org/1999/xhtml">
 <xsl:output omit-xml-declaration="yes" method="xhtml" version="1.0" encoding="UTF-8"
 indent="yes"/>

<xsl:template match="head"/>

<xsl:template match="body">

    <xsl:for-each-group select = "*" group-starting-with = "h1">
        <output>
            <xsl:apply-templates select="current-group()"/>
        </output>
    </xsl:for-each-group>
</xsl:template>

<xsl:template match="*">
    <xsl:element name="{name()}">
        <xsl:apply-templates select="node()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

但是输出没有按我想要的方式工作。我想要两个 output-blocks 作为这个例子的输出:

<html>
<output>
  <div><h1><b>TRAIN</b></h1></div>
  <p>text</p>
  <p>In this field there is text</p>
</output>

<output>
  <div><h1><b>nr1</b><b>CAR</b></h1></div>
  <h2>
     <b>1.</b>
     <b>nr2</b>
     <b>area</b>
  </h2>
  <p>infos about cars</p>
  <p><b>more and</b>more infos about cars</p>
</output>

感谢您的帮助!

您可以使用 descendant-or-self 轴,从具有 h1 作为后代的元素开始分组(或者 h1 元素本身)

<xsl:for-each-group select="*" group-starting-with="*[descendant-or-self::h1]">

另请注意,在您的 XSLT 中您使用了 xpath-default-namespace,但您的输入 XML 未使用该命名空间,因此您的 XSLT 中的 body 模板不会' t 匹配输入。您需要将默认命名空间添加到输入中,或者从 XSLT 中删除 xpath-default-namespace

怎么样:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/html">
    <xsl:copy>
        <xsl:for-each-group select="body/*" group-starting-with="div[h1]">
            <output>
                <xsl:copy-of select="current-group()"/>
            </output>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>