开发者

How to fetch Distinct Values in XSLT

开发者 https://www.devze.com 2023-03-05 04:32 出处:网络
My input file, <?xml version=\"1.0\" encoding=\"UTF-8\"?> <TstData> <ENT_A_BLY Common_Key=\"3195KG\" NAME=\"COMPDATA_AC\"/>

My input file,

<?xml version="1.0" encoding="UTF-8"?>
<TstData>
<ENT_A_BLY Common_Key="3195  KG" NAME="COMPDATA_AC"/>
<SOLUTIONS>
    <A_BLY Name="LPT nozzle cracked." Common_Key="489BB8CC-5978-4D45-B781-929703D1826A">
        <SOLUTION>
            <ID>2060000000000000000001309</ID>
            <TITLE Common_Key="FD08B464-B115-433F-82A9-0B2BC5CC0A4E"> LPT(Low Pressure Turbine) Damage</TITLE>
        </SOLUTION>
        <SOLUTION>
            <ID>206000000000000000001310</ID>
            <TITLE Common_Key="FFDSFE64-8DF9-43RF-8DF9-0DFSD5CC0A4E"> LPT(Low Pressure Turbine) Damage</TITLE>
        </SOLUTION>
        <SOLUTION>
            <ID>2060000000000000000001316</ID>
            <TITLE Common_Key="ADUIEI42-B115-433F-82A9-0B2BC5CC0A4E">Temperature High due开发者_开发知识库 to LPT(Low Pressure Turbine) Damage</TITLE>
        </SOLUTION>     
    </A_BLY>
</SOLUTIONS>
</TstData>

In the XSLT, I am trying to fetch only one TITLE text from the 2 solutions.(as both the TITLE names are same.) so that no duplicate data will be displayed in the output.

My XSLT.. (part shown).

<xsl:element name="FMs">
<xsl:variable name="distinctFM" select="distinct-values(//SOLUTION/TITLE/@Common_Key)"/>
<xsl:for-each select="$distinctFM">
    <xsl:variable name="TITLENAME" select="."/>
    <xsl:variable name="TITLENAME1" select="//SOLUTIONS/A_BLY/SOLUTION/TITLE[@Common_Key=$TITLENAME]"/>
    <xsl:element name="FailureMode">
        <xsl:attribute name="CommonKey"><xsl:value-of select="$TITLENAME"/></xsl:attribute>
        <xsl:attribute name="FMName"><xsl:value-of select="substring(normalize-space($TITLENAME1),1,200)"/></xsl:attribute>
    </xsl:element>
</xsl:for-each>
</xsl:element>

I am expecting the output in this format,

<FM CommonKey="FD08B464-B115-433F-82A9-0B2BC5CC0A4E" FMName="LPT(Low Pressure Turbine) Damage"/>
<FM CommonKey="ADUIEI42-B115-433F-82A9-0B2BC5CC0A4E" FMName="Temperature High due to LPT(Low Pressure Turbine) Damage"/>

But, currently while I debugged, for FMName, it throws error at Variable TITLENAME1. Pls help me in framing this output.

Thanks Ramm


I've worked out what error you are getting even though you didn't give the error message! It's because you are using a path expression starting with "/" when the context item is an atomic value. You need to make the path start with some variable like $root which is bound to the root of the input document before the context changes to the result of distinct-values().


Try this:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="SOLUTIONS">
    <FMs>
      <xsl:apply-templates />
    </FMs>
  </xsl:template>

  <xsl:template match="SOLUTION">
    <FailureMode CommonKey="{TITLE/@Common_Key}" FMName="{TITLE}" />
  </xsl:template>

  <xsl:template match="SOLUTION[preceding-sibling::SOLUTION/TITLE = TITLE]" />
</xsl:stylesheet>

The last template basically overrides the previous one where there's a previous SOLUTION node with the same title as the current one, and outputs nothing.

Alternatively, it can be done using a key:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="FMName" match="SOLUTION" use="TITLE" />

  <xsl:template match="SOLUTIONS">
    <FMs>
      <xsl:apply-templates />
    </FMs>
  </xsl:template>

  <xsl:template match="SOLUTION">
    <xsl:if test="generate-id() = generate-id(key('FMName',TITLE)[1])">
      <FailureMode CommonKey="{TITLE/@Common_Key}" FMName="{TITLE}" />
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

This solution uses an xsl:if to only include nodes that are the first node with the given name.

In this case, I'd recommend the first method personally, but the latter can be more flexible with a more complex XML structure.


You want no duplicate TITLE values? This will get you started!

XSL

<xsl:template match="/">
    <Foobar>
        <xsl:for-each select="//TITLE[not(.=preceding::*)]">
            <xsl:element name="FM">
                <xsl:attribute name="CommonKey"><xsl:value-of select="@Common_Key"/></xsl:attribute>
                <xsl:attribute name="FMName"><xsl:value-of select="."/></xsl:attribute>
            </xsl:element>
        </xsl:for-each>
    </Foobar>
</xsl:template>

Results in:

<Foobar xmlns="http://www.w3.org/1999/xhtml">
    <FM CommonKey="FD08B464-B115-433F-82A9-0B2BC5CC0A4E" FMName=" LPT(Low Pressure Turbine) Damage"></FM>
    <FM CommonKey="ADUIEI42-B115-433F-82A9-0B2BC5CC0A4E" FMName="Temperature High due to LPT(Low Pressure Turbine) Damage"></FM>
</Foobar>

More information can be found here.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号