Rohit Srivastava
Rohit Srivastava

Reputation: 278

Checking multiple attribute values in multiple nodes with XSL

the xml is as follows.

<MyXml>
<Machine1>
    <SupportedOS>
        <OS1 MajorVersion=1 MinorVersion=2/>
        <OS2 MajorVersion=2 MinorVersion=0/>
        <OS3 MajorVersion=1 MinorVersion=1/>
        <OS4 MajorVersion=2 MinorVersion=1/>
        <OS5 MajorVersion=3 MinorVersion=0/>
     </SupportedOS>
 </Machine1>
 </MyXml>

I get the OS version from some source (say MajorVersion=x1 and MinorVersion=x2) inside this XML and Add both the xml programitically. The task is to compare the Both the Minor and Major Version of OS and olny if the both of them are same to the source only then copy the Machine node to the transformed xml. Let me know the ways to do it. I will try to code myself.

EDIT

I want to copy the Machine Node when any one of the OS node has MajorVersion=x1 and MinorVersion=x2.

Upvotes: 2

Views: 5640

Answers (3)

Shil
Shil

Reputation: 221

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml"/>
    <xsl:template match="/MyXml">
        <xsl:apply-templates select="//SupportedOS"/>
    </xsl:template>
    <xsl:template match="SupportedOS">
        <xsl:for-each select="child::*">
            <xsl:if test="@MajorVersion='1' and @MinorVersion='2'">
                <xsl:copy-of select="//Machine1"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243529

As simple as this:

<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:param name="pMajor" select="1"/>
 <xsl:param name="pMinor" select="2"/>

 <xsl:template match="/*/*">
  <xsl:copy-of select=
   "self::*[*/*[@MajorVersion = $pMajor and @MinorVersion = $pMinor]]"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the following XML document (the provided one is severely malformed and not useful!):

<MyXml>
    <Machine1>
        <SupportedOS>
            <OS1 MajorVersion="1" MinorVersion="2"/>
            <OS2 MajorVersion="2" MinorVersion="0"/>
            <OS3 MajorVersion="1" MinorVersion="1"/>
            <OS4 MajorVersion="2" MinorVersion="1"/>
            <OS5 MajorVersion="3" MinorVersion="0"/>
        </SupportedOS>
    </Machine1>
    <Machine2>
        <SupportedOS>
            <OS1 MajorVersion="1" MinorVersion="3"/>
            <OS2 MajorVersion="2" MinorVersion="0"/>
            <OS3 MajorVersion="1" MinorVersion="1"/>
            <OS4 MajorVersion="2" MinorVersion="1"/>
            <OS5 MajorVersion="3" MinorVersion="0"/>
        </SupportedOS>
    </Machine2>
</MyXml>

the wanted, correct result is produced:

<Machine1>
   <SupportedOS>
      <OS1 MajorVersion="1" MinorVersion="2"/>
      <OS2 MajorVersion="2" MinorVersion="0"/>
      <OS3 MajorVersion="1" MinorVersion="1"/>
      <OS4 MajorVersion="2" MinorVersion="1"/>
      <OS5 MajorVersion="3" MinorVersion="0"/>
   </SupportedOS>
</Machine1>

Upvotes: 2

Rookie Programmer Aravind
Rookie Programmer Aravind

Reputation: 12154

Compare attributes if they aren't satisfying the condition .. if yes then drop them..

Or else copy them

in the below code, first template copies all nodes,
second template drops OS that is having MajorVersion not equal to 'x1' and MinorVersion not equal to 'x2'

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
  <xsl:template match="/MyXml/Machine1/SupportedOS/OS1[@MajorVersion != 'x1' and @MajorVersion!='x2']"/>
</xsl:stylesheet>

Upvotes: 1

Related Questions