XSLT用于选择对应于一个字段的第一个细节

时间:2014-10-17 04:21:19

标签: xslt

我正在编写xslt,用于根据其中一个字段过滤数据。

这是我的输入xml:

   <?xml version="1.0" encoding="UTF-8"?>
 <Consumer>
<header>
    <msfnm>MSFNM</msfnm>
    <mslnm>MSLNM</mslnm>
    <msmnm>MSMNM</msmnm>
    <msssn>MSSSN</msssn>
    <csscstno>CSSCSTNO</csscstno>
    <msact>MSACT</msact>
 </header>
<data>
    <msfnm>Nitin</msfnm>
    <mslnm>Jain</mslnm>
    <msmnm/>
    <msssn>123</msssn>
    <csscstno>111</csscstno>
    <msact>1234</msact>
 </data>
 <data>
    <msfnm>Nitin1</msfnm>
    <mslnm>Jain1</mslnm>
    <msmnm>L1</msmnm>
    <msssn>1233</msssn>
    <csscstno>111</csscstno>
    <msact>1233556</msact>
 </data>
 <data>
    <msfnm>Nitin2</msfnm>
    <mslnm>Jain2</mslnm>
    <msmnm>L1</msmnm>
    <msssn>1234</msssn>
    <csscstno>123</csscstno>
    <msact>12334256</msact>
 </data>
 <data>
    <msfnm>Nitin</msfnm>
    <mslnm>Jain</mslnm>
    <msmnm/>
    <msssn>123</msssn>
    <csscstno>111</csscstno>
    <msact>1234</msact>
 </data>

我希望我的输出xml应该像

 <?xml version="1.0" encoding="UTF-8"?>
<Consumer>
   <data>
    <msfnm>Nitin</msfnm>
    <mslnm>Jain</mslnm>
    <msmnm/>
    <msssn>123</msssn>
    <csscstno>111</csscstno>
    <msact>1234</msact>
 </data>
    <data>
    <msfnm>Nitin2</msfnm>
    <mslnm>Jain2</mslnm>
    <msmnm>L1</msmnm>
    <msssn>1234</msssn>
    <csscstno>123</csscstno>
    <msact>12334256</msact>
 </data>

 </Consumer>

条件:基本上我想要的,只取第一次出现的csscstno。如果在下一次出现时csscstno相同,则应拒绝整个集合。

我的xslt:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <xml>
      <xsl:for-each select="/Consumer/data">

             <Consumer>
                <msfnm><xsl:value-of select="msfnm"/></msfnm>
                <mslnm><xsl:value-of select="mslnm"/></mslnm>
                <msmnm><xsl:value-of select="msmnm"/></msmnm>
                <msssn><xsl:value-of select="msssn"/></msssn>
<xsl:if test="position()=1">
                <csscstno><xsl:value-of select="csscstno"/></csscstno>
  </xsl:if>
                <msact><xsl:value-of select="msact"/></msact>  
             </Consumer>

   </xsl:for-each>
  </xml>
</xsl:template>
</xsl:stylesheet>

这不起作用。让我知道,我在这里做错了什么。

3 个答案:

答案 0 :(得分:0)

或者,您可以使用密钥通过csscstno对数据进行分组以获得第一次出现。此外,您可以使用副本来选择&#34;数据&#34;:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="dataByCsscstno" match = "data" use = "csscstno"/>
<xsl:template match="/">
    <Consumer>
        <xsl:copy-of select="/Consumer/data[generate-id() = generate-id(key('dataByCsscstno', csscstno)[1])]"/>
    </Consumer>
</xsl:template>
</xsl:stylesheet>

答案 1 :(得分:0)

您可以使用密钥。就像下面的样式表一样:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes" />

    <!-- create a key for your target node -->
    <xsl:key name="Customer_No" match="csscstno" use="."/>

    <!-- copy only the 1st matched keys in the output -->
    <xsl:template match="/">
        <Consumer>
            <xsl:copy-of select="Consumer/data[count(csscstno | key('Customer_No', csscstno)[1]) = 1]"/>
            <!-- or you can use the following line instead
            <xsl:copy-of select="Consumer/data[generate-id(csscstno) = generate-id(key('Customer_No', csscstno)[1])]"/>
            -->
        </Consumer>
    </xsl:template>

</xsl:transform>

当它应用于您的输入XML时,结果为:

<?xml version="1.0" encoding="utf-8"?>
<Consumer>
   <data>
      <msfnm>Nitin</msfnm>
      <mslnm>Jain</mslnm>
      <msmnm/>
      <msssn>123</msssn>
      <csscstno>111</csscstno>
      <msact>1234</msact>
   </data>
   <data>
      <msfnm>Nitin2</msfnm>
      <mslnm>Jain2</mslnm>
      <msmnm>L1</msmnm>
      <msssn>1234</msssn>
      <csscstno>123</csscstno>
      <msact>12334256</msact>
   </data>
</Consumer>

答案 2 :(得分:0)

最终我找到了另一种方法,它按预期工作。

这是我的xslt:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xml>
  <xsl:for-each-group select="/Consumer/data" group-by="csscstno">
       <xsl:copy-of select="current-group()[1]"/>
  </xsl:for-each-group>            
</xml>
</xsl:template>
</xsl:stylesheet>