0
votes

I have a XML structure where i need to apply filtering for nodes and out of the filtered nodes i need to select specific elements. The structure of actual XML looks like this-

 <Host> 
   <element1>type0</element1>
   <element2>Fruits</element2>
   ....
   <elementn>Price0</elementn>   
   <Menu>
   <NodeA>
     <element1>type1</element1>
     <element2>Fruits</element2>
     ....
     <elementn>Price1</elementn>
     <Menu>
     <NodeB>
       <element1>type2</element1>
       <element2>Fruits</element2>
       ....
       <elementn>Price2</elementn>
       <Menu>
       <NodeC>
         <element1>type3</element1>
         <element2>Fruits</element2>
         ....
         <elementn>Price3</elementn>
         <Menu>
         <NodeD>
           <Element1>type4</element1>
           <Element2>Vegetables</Element2>
           ....
           <Elementn>Price4</elementn>  
         </NodeD>
         </Menu>    
       </NodeC>
       </Menu>
     </NodeB>
     </Menu>
   </NodeA>
   <NodeE>
     <element1>type5</element1>
     <element2>Fruits</element2>
     ....
     <elementn>Price5</elementn>
     <Menu>
     <NodeF>
       <element1>type6</element1>
       <element2>Vegetables</element2>
       ....
       <elementn>Price6</elementn>
     </NodeF> 
     </Menu>  
   </NodeE>  
   </Menu> 
 </Host>

Now I have filtered this XML as follows- a) if <element2> == fruits in all the nodes, the XML result is -

<Host> 
  <element1>type0</element1>
  <element2>Fruits</element2>
  ....
  <elementn>Price0</elementn>
  <NodeA>
    <element1>type1</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price1</elementn>
  </NodeA>
  <NodeB>
    <element1>type2</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price2</elementn>
  </NodeB>
  <NodeC>
    <element1>type3</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price3</elementn>
  </NodeC>
  <NodeE>
    <element1>type5</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price5</elementn>
  </NodeE>    
</Host>

XSLT used for getting the above result is-

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

<xsl:param name="element2" select="'Fruits'" />

<xsl:template match="/*">
    <xsl:copy>
        <xsl:apply-templates select="//*[element2=$element2]" mode="copy"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="*[element2]" mode="copy">
    <xsl:copy>
        <xsl:apply-templates select="*[not(*)]" mode="copy"/>
    </xsl:copy>
</xsl:template>

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

The above XSLT select all the elements in the node where <element2> = Fruits condition is applied. Now I need to select specific elements in each filtered node (<Host>, <NodeA>, <NodeB>, <NodeC>, <NodeE>) - say for every node, i have elements range from to . Now I want to select only and from filtered nodes (<Host>, <NodeA>, <NodeB>, <NodeC>, <NodeE>). Also the expected output format is given below. The two values in each given below is from and of each node.

<html>
 <head>
 <body>
 <table border="1">
  <tr>
    <td>type0</td>
    <td>Price0</td>
  </tr>
    <td>type1</td>
    <td>Price1</td>
  </tr>
  <tr>
    <td>type2</td>
    <td>Price2</td>
  </tr>
  <tr>
    <td>type3</td>
    <td>Price3</td>
  </tr>
  <tr>
    <td>type5</td>
    <td>Price5</td>
  </tr>    
 </table>
 </body>
 </head>
</html>

Any help would be a great plus.

1
Where did that Node0 in your output come from? It's nowhere in the input or in the XSLT. Also, "Now I need to pick specific elements in each node." What does this mean? This appears to be the crux of your question and it doesn't tell us anything useful. - JLRishe
You could see the changes in questions - QA Testing
You've completely changed your output, but you haven't clarified your question. Please explain what you want to do. You can also explain by describing an example, like "For example, I would like to change X to Y and change M to N and only include U and V". - JLRishe
It's difficult to understand what in your example is known and what is just an example - esp. when it comes to the names of the elements. - michael.hor257k
XMLis case-sensitive: /element1> does not close <Element1>. - michael.hor257k

1 Answers

0
votes

It seems you want to do something like:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:param name="element2" select="'Fruits'" />

<xsl:template match="/">
    <html>
        <head/>
        <body>
            <table border="1">
                <xsl:for-each select="//*[element2=$element2]">
                     <tr>
                        <td>
                            <xsl:value-of select="element1" />  
                        </td>
                        <td>
                            <xsl:value-of select="elementn" />  
                        </td>
                    </tr>
                </xsl:for-each>
            </table>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

When this is applied to the following well-formed (!) input:

XML

<Host>
   <element1>type0</element1>
   <element2>Fruits</element2>
   <elementn>Price0</elementn>
   <Menu>
      <NodeA>
         <element1>type1</element1>
         <element2>Fruits</element2>
         <elementn>Price1</elementn>
         <Menu>
            <NodeB>
               <element1>type2</element1>
               <element2>Fruits</element2>
               <elementn>Price2</elementn>
               <Menu>
                  <NodeC>
                     <element1>type3</element1>
                     <element2>Fruits</element2>
                     <elementn>Price3</elementn>
                     <Menu>
                        <NodeD>
                           <element1>type4</element1>
                           <element2>Vegetables</element2>
                           <elementn>Price4</elementn>
                        </NodeD>
                     </Menu>
                  </NodeC>
               </Menu>
            </NodeB>
         </Menu>
      </NodeA>
      <NodeE>
         <element1>type5</element1>
         <element2>Fruits</element2>
         <elementn>Price5</elementn>
         <Menu>
            <NodeF>
               <element1>type6</element1>
               <element2>Vegetables</element2>
               <elementn>Price6</elementn>
            </NodeF>
         </Menu>
      </NodeE>
   </Menu>
</Host>

the result will be:

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   </head>
   <body>
      <table border="1">
         <tr>
            <td>type0</td>
            <td>Price0</td>
         </tr>
         <tr>
            <td>type1</td>
            <td>Price1</td>
         </tr>
         <tr>
            <td>type2</td>
            <td>Price2</td>
         </tr>
         <tr>
            <td>type3</td>
            <td>Price3</td>
         </tr>
         <tr>
            <td>type5</td>
            <td>Price5</td>
         </tr>
      </table>
   </body>
</html>

rendered as:

enter image description here