Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
211 views
in Technique[技术] by (71.8m points)

xml - Logic for creating multiple rows for BIOSRelDate and BIOSVersion combination

Could you please advise on how I can build the XSLT logic using the below XML? I need to be able to sort by BIOSReldate and create two rows for BIOSReldate and BIOSVersion combination.

My final output should have the following attributes in a .CSV

Description, Class, HardwareID, Vendor, BIOSRelDate, BIOSVersion

<!---

There are two BIOSRelDate and BIOSVersion instances and need to generate them as multiple rows

 <Device Count="1" Description="xxxx System Management BIOS Driver"   
 Class="System" DeviceType="Smbios">
      <HardwareIDs>
        <ID Value="ROOTmssmbios" />
      </HardwareIDs>
      <Properties>
        <Vendor Value="American Megatrends Inc." />
        <BIOSRelDate Value="11/02/2016" />
        <BIOSVersion Value="C1043.BS.4A16.AH1" />
        <BIOSRelDate Value="10/02/2017" />
        <BIOSVersion Value="C1043.BS.4A25.AH1" />
      </Properties>
</Device>

Below is what I tried -

<xsl:apply-templates select="Device/Properties">
    <xsl:sort select="BIOSRelDate" data-type="number" order="ascending"/>
</xsl:apply-templates>
...
<xsl:template match="BIOSRelDate">
    <!--Duplicate all Properties data for each BIOSRelDate-->
    <Device>
        <xsl:value-of select="../*[not(self::BIOSRelDate)] | ."/>
    </Device>
</xsl:template>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Try it this way?

XSLT 1.0

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/Device">
    <!-- HEADER -->
    <xsl:text>Description, Class, HardwareID, Vendor, BIOSRelDate, BIOSVersion&#10;</xsl:text>
    <!-- COMMON DATA -->
    <xsl:variable name="common">
        <xsl:value-of select="@Description"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="@Class"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="HardwareIDs/ID/@Value"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="Properties/Vendor/@Value"/>
        <xsl:text>,</xsl:text>
    </xsl:variable>
    <!-- GENERATE ROWS -->
    <xsl:for-each select="Properties/BIOSRelDate">
        <!-- SORT BY YEAR -->
        <xsl:sort select="substring(@Value, 7, 4)" data-type="number"/>
        <!-- SORT BY MONTH -->
        <xsl:sort select="substring(@Value, 1, 2)" data-type="number"/>
        <!-- SORT BY DAY -->
        <xsl:sort select="substring(@Value, 4, 2)" data-type="number"/>
        <!-- OUTPUT -->
        <xsl:value-of select="$common"/>        
        <xsl:value-of select="@Value"/>
        <xsl:text>,</xsl:text>
        <xsl:value-of select="following-sibling::BIOSVersion[1]/@Value"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

Applied to your input example, the result will be:

Description, Class, HardwareID, Vendor, BIOSRelDate, BIOSVersion
xxxx System Management BIOS Driver,System,ROOT\mssmbios,American Megatrends Inc.,11/02/2016,C1043.BS.4A16.AH1
xxxx System Management BIOS Driver,System,ROOT\mssmbios,American Megatrends Inc.,10/02/2017,C1043.BS.4A25.AH1

Note that I assumed that your date format is MM/DD/YYYY. Your example is ambiguous in that regard. If it's DD/MM/YYYY, make the necessary adjustment.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...