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 questionsQA 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