如果找到两个相同的元素,则在转换时删除一个元素

时间:2011-10-19 11:28:25

标签: xml xslt

我使用XSLT一次转换多个文档。那些文件可能有像这样的元素 <a:updated></a:updated><app:edited></app:edited>,其中一些同时拥有<a:updated></a:updated><app:edited></app:edited>

在这种情况下,一些输出的文档(除了它的标准元素,如标题,链接,内容)有两倍<posted></posted>元素。

此处的问题是,如果在同一<posted></posted>中找到<app:edited><a:updated>,我该如何删除<entry></entry>

这是XSLT的标题

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:a="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app">

这是模板

<xsl:template match="a:updated | app:edited">
  <posted>    
    <xsl:apply-templates select="node() | @*" />
  </posted>
</xsl:template>

这就是我处理它的方式

$xproc = new XsltProcessor();
$xslt = new DomDocument;
$xslt->load('stylesheet.xslt');
$xproc->importStylesheet($xslt);

这基本上就是XML

<entry>
<id></id>
<title></title>
<content></content>
<link></link>
<a:updated></a:updated>
<app:edited></app:edited>
</entry> 

1 个答案:

答案 0 :(得分:0)

正确的答案取决于您尚未显示的源XML文档。

一般情况下,如何以及是否选择执行模板取决于选择此模板的<xsl:apply-templates>指令,请尝试以下操作:

<xsl:apply-templates select=
  "(//*
     [self::a:updated 
     or 
      self::updated 
     or self::app:edited
     ]) 
      [1]
"/>

如果可能的话,尝试用更具体的XPath表达式替换上面的//伪运算符,因为//因其低效性而臭名昭着。

更新:既然OP发布了XML文档,这是一个更具体的解决方案:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:a="a" xmlns:app="app" exclude-result-prefixes="a app"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
    <xsl:apply-templates select=
      "(/*/*
         [self::a:updated
         or
          self::updated
         or self::app:edited
         ])
          [1]
    "/>
 </xsl:template>

 <xsl:template match="a:updated | app:edited">
      <posted>
        <xsl:apply-templates select="node() | @*" />
      </posted>
 </xsl:template>
</xsl:stylesheet>

将此转换应用于提供的XML文档(按摩以使格式正确):

<entry xmlns:a="a" xmlns:app="app">
    <id></id>
    <title></title>
    <content></content>
    <link></link>
    <a:updated></a:updated>
    <app:edited></app:edited>
</entry>

想要的正确结果<posted>仅在输出中出现一次)生成

<posted/>