如何选择特定父节点中的先前节点

时间:2012-04-26 17:29:18

标签: xslt-1.0

给出以下xml

   <Root>
 <Employee>
   <service>
     <Record>xxx</Record>
     <Record>yyy</Record>
   </service>
   <service>
    <Record>xxx</Record>
    <Record>yyy</Record>
    <Record>zzz</Record>
   </service>
</Employee>
<Employee>
  <service>
     <Record>xxx</Record>
     <Record>yyy</Record>
   </service>
   <service>
    <Record>xxx</Record>
    <Record>yyy</Record>
    <Record>zzz</Record>
   </service>
</Employee>
</Root>

使用XSLT1.0,在为每个<Employee>转换包含'xxx'的<Record>字段的xml时,'yyy','zzz'应该只在结果中出现一次

<Root>
 <Employee>
    <Service>
     <Record>xxx</Record>
     <Record>yyy</Record>
     <Record>zzz</Record>
   </Service>
</Employee>
<Employee> 
  <Service>
  <Record>xxx</Record>
  <Record>yyy</Record>
  <Record>zzz</Record>
 <Service>
</Employee>
</Root>

在员工的for-each循环中,我厌倦了使用<xsl:if test='not(preceding::./service/Record=$record)'>。该测试适用于第一个<Employee>仅针对'xxx','yyy','zzz'的<Record>。当迭代进入下一个<Employee>时,测试条件也检查第一个<Record>中的<Employee>值,并且它找到前面的节点已经存在值'xxx','yyy' ,'zzz',因此我无法获得第二个<Employee>的记录。 如何在第二个<Record>中获取<Employee> s。非常感谢任何帮助。

谢谢

1 个答案:

答案 0 :(得分:0)

此转换使用Muenchian方法进行分组

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

 <xsl:key name="kEmpRecordByVal" match="Employee/service/Record"
  use="concat(generate-id(../..), '+', .)"/>

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

 <xsl:template match="Employee">
  <Employee>
    <xsl:apply-templates select=
     "service/Record
           [generate-id()
           =
            generate-id(key('kEmpRecordByVal',
                            concat(generate-id(../..), '+', .)
                            )[1]
                        )
           ]
     "/>
  </Employee>
 </xsl:template>
</xsl:stylesheet>

应用于以下XML文档(提供的第二个Employee具有不同的值以帮助提高可读性):

<Root>
    <Employee>
        <service>
            <Record>xxx</Record>
            <Record>yyy</Record>
        </service>
        <service>
            <Record>xxx</Record>
            <Record>yyy</Record>
            <Record>zzz</Record>
        </service>
    </Employee>
    <Employee>
        <service>
            <Record>aaa</Record>
            <Record>bbb</Record>
        </service>
        <service>
            <Record>aaa</Record>
            <Record>bbb</Record>
            <Record>ccc</Record>
        </service>
    </Employee>
</Root>

产生了想要的正确结果:

<Root>
   <Employee>
      <Record>xxx</Record>
      <Record>yyy</Record>
      <Record>zzz</Record>
   </Employee>
   <Employee>
      <Record>aaa</Record>
      <Record>bbb</Record>
      <Record>ccc</Record>
   </Employee>
</Root>