使用xsl更改位于其他特定元素后面的元素的名称

时间:2013-09-26 20:54:35

标签: xml xslt transform

我有一个这样的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元素)。

这个想法是在转换之后输出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>

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

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

我不确定你对不允许兄弟轴的意思是什么,因为以下内容应该有效

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

即。匹配 p 元素,其第一个前兄弟是 title 元素。

或者,如果它可以是任何元素,而不仅仅是 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>

答案 1 :(得分:1)

不确定你是怎么回事“它不允许我使用兄弟姐妹轴”,但以下工作:

<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>