繁体   English   中英

使用XSLT更改XML文件中的一个标记名称

[英]Changing One Tag Name in an XML File Using XSLT

我是否可以在XSLT中使用条件,以便仅查找和替换特定标记名称的FIRST标记?

例如,我有一个包含许多<title>标签的XML文件。 我想用<PageTitle>替换这些标签中的第一个。 其余部分应该保持不变。 我如何在变换中做到这一点? 我现在拥有的是:

<xsl:template match="title">
     <PageTitle>
       <xsl:apply-templates />
     </PageTitle>
</xsl:template>

它找到所有<title>标签并用<PageTitle>替换它们。 任何帮助将不胜感激!

文档中的第一个title元素通过以下方式选择

(//title)[1]

许多人错误地认为//title[1]选择了文档中的第一个title ,这是一个经常犯的错误。 //title[1]选择每个title元素,它是其父级的第一个title子元素 - 不是这里想要的。

使用此,以下转换将生成所需的输出

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

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

 <xsl:template match=
  "title[count(.|((//title)[1])) = 1]">

     <PageTitle>
       <xsl:apply-templates />
     </PageTitle>
 </xsl:template>
</xsl:stylesheet>

应用于此XML文档时

<t>
 <a>
  <b>
    <title>Page Title</title>
  </b>
 </a>
 <b>
  <title/>
 </b>
 <c>
  <title/>
 </c>
</t>

产生了想要的结果

<t>
 <a>
  <b>
    <PageTitle>Page Title</PageTitle>
  </b>
 </a>
 <b>
  <title />
 </b>
 <c>
  <title />
 </c>
</t>

请注意我们如何在XPath 1.0中使用众所周知的Kaysian方法设置交集

如果有两个节点集$ns1$ns2 ,则以下表达式选择属于$ns1$ns2每个节点:

$ns1[count(.|$ns2) = count($ns2)]

在特定情况下,当两个节点集仅包含一个节点 ,并且其中一个节点是当前节点时,以下表达式在两个节点完全相同时精确计算为true()

count(.|$ns2) = 1

在模板的匹配模式中使用此变体来覆盖标识规则:

title[count(.|((//title)[1])) = 1]

仅匹配文档中的第一个title元素。

这应该工作:

<xsl:template match="title[1]">
     <PageTitle>
       <xsl:apply-templates />
     </PageTitle>
</xsl:template>

但它在每种情况下都匹配第一个标题。 因此,在以下示例中, /a/x/title[1]/a/title[1]都将匹配。 所以你可能想要指定类似match="/a/title[1]"

<a>
    <x>
        <title/> <!-- first title in the context -->
    </x>
    <title/> <!-- first title in the context -->
    <title/>
    <c/>
    <title/>
</a>

如果所有标题标签都是兄弟,您可以使用:

<xsl:template match="title[1]">
    <PageTitle>
        <xsl:apply-templates />
    </PageTitle>
</xsl:template> 

但是,这将匹配作为任何节点的第一个子节点的所有title元素。 如果标题可能具有不同的父节点,并且您只希望将整个文档中的第一个标题替换为PageTitle ,则可以使用

<xsl:template match="title[not(preceding::title or ancestor::title)]">
    <PageTitle>
        <xsl:apply-templates />
    </PageTitle>
</xsl:template>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM