XSLT2 - 测试哪个节点在选项中排在第一位

时间:2016-10-18 08:11:28

标签: xml xslt

鉴于这种结构:

<body>
  <h1>Main Title</h1>
  <p class="sectiontitle>Title</p>
  <p class="bodytext">some text</bodytext>
  <ul>...</ul>
  <p class="paragraphtitle>Subtitle</p>
  <p class="bodytext">some text</bodytext>
</body>

或者这个章节标题和章节标题相反:

<h1>Main Title</h1>
  <p class="paragraphtitle>Title</p>
  <p class="bodytext">some text</bodytext>
  <ul>...</ul>
  <p class="sectiontitle>Subtitle</p>
  <p class="bodytext">some text</bodytext>
</body>

我正在将这个XML结构转换为不同的XML(DITA),为此,我需要知道什么节点首先出现,因为它告诉我如何处理文件的其余部分。
在我知道首先出现的情况之前,没有其他方法可以处理文件 我知道在任何这些游戏之前会有一个h1,h2,h3 ...元素。主标题和结束标记之间可能有<p class=bodytext>个元素。这是非常随意的。

我如何判断第一个是什么:sectiontitle p或paragraphtitle p。

我尝试过一些疯狂的表达式,如下所示:

body/p[@class='sectiontitle'][1]/preceding-sibling::p[@class!='paragraphtitle'][last()]/preceding-sibling::*[not(self::p[@class='sectiontitle' or @class='paragraphtitle']) and preceding-sibling::h1]

body/p[@class='paragraphtitle'][1]/preceding-sibling::p[@class!='sectiontitle'][last()]/preceding-sibling::*[not(self::p[@class='sectiontitle' or @class='paragraphtitle']) and preceding-sibling::h1]

这在大多数情况下都有效(仍然需要调整一些东西),但我觉得必须有一些更简单的东西可以告诉哪个节点在可能性列表中排在第一位。

有没有办法获得绝对的位置?像

这样的东西
if absposition(paragraphtitle[1]) < absposition(sectiontitle[1]) then

2 个答案:

答案 0 :(得分:0)

在XSLT 2.0中,您可以使用<<运算符:

if (p[@class='paragraphtitle'] << p[@class='sectiontitle']) ...

在1.0中,除了兄弟姐妹和兄弟姐妹之外,你没有其他选择。但我不能真正建议细节,因为你的候选表达式包括不需要区分这两个样本的细节(例如测试两者中存在的h1元素),以及我假设你把那些额外的条件放在那里是有原因的。

另一个选项(需要节点集扩展)是通过排除所有不感兴趣的元素来过滤列表,然后使用<xsl:if test="p[1][self::sectiontitle]">测试过滤后的列表。

或许有人应该问你为什么这样做,真正的潜在问题是什么?也许你真正的目标是将元素重新排序为一些规范顺序,在这种情况下,我们应该关注排序技术。

答案 1 :(得分:0)

  

有没有办法获得绝对的位置?像是的东西   absposition(paragraphtitle[1]) < absposition(sectiontitle[1]) then

我相信你的情况可以重申为:

  

如果在第一个paragraphtitle之前有sectiontitle,那么......

可以表示为:

<xsl:choose>
    <xsl:when test="/body/p[@class='sectiontitle'][1]/preceding-sibling::p[@class='paragraphtitle']">paragraph title is first</xsl:when>
    <xsl:otherwise>section title is first</xsl:otherwise>
</xsl:choose>

这适用于XSLT 1.0和2.0。如前所述,在XSLT 2.0中,您可以对测试进行建模,使其完全符合您的原始语句:

<xsl:when test="/body/p[@class='paragraphtitle'][1] &lt;&lt; /body/p[@class='sectiontitle'][1]">paragraph title is first</xsl:when>

或:

<xsl:when test="/body/p[@class='sectiontitle'][1] >> /body/p[@class='paragraphtitle'][1]">paragraph title is first</xsl:when>
相关问题