使用 xsl 更改放置在另一个特定元素之后的元素的名称

Posted

技术标签:

【中文标题】使用 xsl 更改放置在另一个特定元素之后的元素的名称【英文标题】:use xsl to change the name of an element which is placed right after another specific element 【发布时间】:2013-10-03 00:41:46 【问题描述】:

我有一个这样的 XML 文件:

<section>
  <section>
    <title>this is title 1</title>
    <p> first paragraph after the title for which I need to change the element name </p>
    <p>second paragraph</p>
    <p>second paragraph</p>
  </section>
  <section>
    <p>paragraph</p>
    <title>this is title 1</title>
    <p> first paragraph after the title for which I need to change the element name </p>
    <p>second paragraph</p>
    <p>second paragraph</p>
  </section>
</section>

我需要找出一个 XSL 转换,它将在标题元素之后(标题元素之后的第一个 p 元素)更改每个 &lt;p&gt; 元素的元素名称。

这个想法是,转换后的输出 xml 应该如下所示:

<section>
  <section>
    <title>this is title 1</title>
    <p_title> first paragraph after the title for which I need to change the element name </p_title>
    <p>second paragraph</p>
    <p>second paragraph</p>
  </section>
  <section>
    <p>paragraph</p>
    <title>this is title 1</title>
    <p_title> first paragraph after the title for which I need to change the element name </p_title>
    <p>second paragraph</p>
    <p>second paragraph</p>
  </section>
</section>

我找不到允许我选择此类元素的模板选择表达式,因为它不允许我使用兄弟轴。

有什么建议吗?

【问题讨论】:

【参考方案1】:

我不确定你的意思是不允许同级轴,因为以下应该可以工作

<xsl:template match="p[preceding-sibling::*[1][self::title]]">

即匹配第一个前导元素是 title 元素的 p 元素。

或者,如果它可以是任何元素,而不仅仅是 p,这应该可以:

<xsl:template match="*[preceding-sibling::*[1][self::title]]">

试试下面的 XSLT

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

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

   <xsl:template match="*[preceding-sibling::*[1][self::title]]">
      <xsl:element name="local-name()_title">
         <xsl:apply-templates select="@*|node()"/>
      </xsl:element>
   </xsl:template>
</xsl:stylesheet>

【讨论】:

【参考方案2】:

不知道你在说什么“它不允许我使用兄弟轴”,但以下工作:

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

  <!-- The identity transform. -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates />
    </xsl:copy>
  </xsl:template>

  <!-- Match p elements where the first preceding sibling is a title element. -->
  <xsl:template match="p[preceding-sibling::*[1][self::title]]">
    <p_title>
      <xsl:apply-templates select="node()|@*"/>
    </p_title>
  </xsl:template>

</xsl:stylesheet>

【讨论】:

以上是关于使用 xsl 更改放置在另一个特定元素之后的元素的名称的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 XSL 选择特定元素节点中的所有文本节点?

如何在另一个元素之后添加一个元素?

Tkinter Listbox 以蓝色突出显示一个元素,但在另一个元素周围放置黑色边框?

如何使用 XSL 将小写转换为大写而不更改内部元素

xsl如何根据来自不同元素的属性汇总一种特定类型元素的总和

XSL1.0:在重复中选择特定元素