如何使用XSL在xml中查找上一个标记?

如何使用XSL在xml中查找上一个标记?,xml,xslt,Xml,Xslt,我有一个XML文件,如下所示 <p>Sample Content 1</p> <p>Sample Content 2</p> <sec level="1">Sample Content 3</sec> <p>Sample Content 4</p> <p>Sample Content 5</p> 样本内容1 样本内容2 样本内容3 样本内容4 样本含量5 XSL转换: &l

我有一个XML文件,如下所示

<p>Sample Content 1</p>
<p>Sample Content 2</p>
<sec level="1">Sample Content 3</sec>
<p>Sample Content 4</p>
<p>Sample Content 5</p>
样本内容1

样本内容2

样本内容3 样本内容4

样本含量5

XSL转换:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="p">
 <xsl:choose>
  <xsl:when test="preceding-sibling::p">
   <p class="indent"><xsl:apply-templates /></p>
  </xsl:when>
  <xsl:otherwise>
   <p class="noindent"><xsl:apply-templates /></p>
  </xsl:otherwise>
 </xsl:choose>
</xsl:template>
</xsl:stylesheet>

我需要以下格式的输出

<p class="noindent">Sample Content 1</p>
<p class="indent">Sample Content 2</p>
<h1>Sample Content 3</h1>
<p class="noindent">Sample Content 4</p>
<p class="indent">Sample Content 5</p>

样本内容1

样本内容2

样本内容3 样本内容4

样本内容5

请说出以上概念的想法。所以我必须找出前面的标签格式


提前感谢。

将条件移动到匹配模式中,并将条件更改为前面的同级::*[1][self::p]:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

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

    <xsl:template match="p">
        <p class="noindent">
            <xsl:apply-templates/>
        </p>
    </xsl:template>
    <xsl:template match="p[preceding-sibling::*[1][self::p]]">
        <p class="indent">
            <xsl:apply-templates/>
        </p>
    </xsl:template>
</xsl:transform>


将条件移动到匹配模式中,并将条件更改为前面的同级:*[1][self::p]:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

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

    <xsl:template match="p">
        <p class="noindent">
            <xsl:apply-templates/>
        </p>
    </xsl:template>
    <xsl:template match="p[preceding-sibling::*[1][self::p]]">
        <p class="indent">
            <xsl:apply-templates/>
        </p>
    </xsl:template>
</xsl:transform>


您唯一的错误是认为
前面的兄弟姐妹::p
表示“紧挨着前面的兄弟姐妹是
p
”,而实际上它表示“前面的兄弟姐妹中至少有一个
p
”。在测试中,将前面的兄弟姐妹::p替换为前面的兄弟姐妹::*[1]/self::p


Martin Honnen建议的结构更改(使用多个模板而不是一个模板)通常是一个好主意,但与代码未能满足您的期望无关。

您唯一的错误是认为
前面的兄弟::p
意味着“前面的兄弟是
p
”,而实际上它意味着“在前面的兄弟姐妹中至少有一个
p
。在测试中,将
前面的兄弟姐妹::p
替换为
前面的兄弟姐妹::*[1]/self::p


Martin Honnen建议的结构更改(使用多个模板而不是一个模板)通常这是一个好主意,但与代码未能满足您的期望无关。

为什么需要查找上一个标记?请在问题中添加您的xsl实验。您使用的xslt版本?您得到了答案。如果使用saxon,您可以使用计数器验证条件。为什么需要查找上一个标记?请添加有问题的xsl实验您使用的.xslt版本?您得到了答案。如果您使用saxon,您可以使用计数器验证条件。