1

I wish to delete few nodes in an xml and add new a node. Let me illustrate with the following xml:

<resprocessing>
  <respcondition title="Correct" continue="No">
    <conditionvar>
      <varequal respident="Response_0">
        <nhm_blank_name>Answer:</nhm_blank_name>
        <nhm_numerator>14</nhm_numerator>
        <nhm_denominator>25</nhm_denominator>
        <nhm_allow_multiples>No</nhm_allow_multiples>
      </varequal>
    </conditionvar>
  </respcondition>
</resprocessing>

I want to remove the nodes <nhm_numerator> and <nhm_denominator> and insert a new node(<nhm_blank_value>) under <varequal>while retaining the other two nodes <nhm_blank_name> <nhm_allow_multiples>

The new node has a value like this:

<nhm_blank_value>
<math xmlns="http://www.w3.org/1998/Math/MathML">
  <mfrac>
    <mn>14</mn>
    <mn>25</mn>
  </mfrac>
</math>
</nhm_blank_value>

I used the following XSLT to successfully delete the aforementioned nodes. But i couldn't add the new node. Please tell me where I m going wrong

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="mathml">
  <nhm_blank_value>
    <math xmlns="http://www.w3.org/1998/Math/MathML">
      <mfrac>
        <mn>14</mn>
        <mn>25</mn>
      </mfrac>
    </math>
  </nhm_blank_value>
 </xsl:param>
<!-- copy the xml as it is -->   
   <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
   <!-- deleting nodes numerator and denominator -->
   <xsl:template  match="questestinterop/item/resprocessing/respcondition/conditionvar/varequal/nhm_denominator" />
   <xsl:template    match="questestinterop/item/resprocessing/respcondition/conditionvar/varequal/nhm_numerator" />   
   <!-- adding mathml node -->
   <xsl:template match="questestinterop/item/resprocessing/respcondition/conditionvar">
     <xsl:value-of select="varequal">
       <xsl:with-param name="mathml"/>
     </xsl:value-of>
   </xsl:template>   
</xsl:stylesheet>
jaykumarark
  • 2,359
  • 6
  • 35
  • 53

1 Answers1

1

I would do something like 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="*" />

  <!-- copy the xml as it is -->   
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- delete denominator -->
  <xsl:template  match="nhm_denominator" />

  <!-- replace numerator with mathml fragment -->
  <xsl:template match="nhm_numerator">
    <nhm_blank_value>
      <math xmlns="http://www.w3.org/1998/Math/MathML">
        <mfrac>
          <mn><xsl:value-of select="." /></mn>
          <mn><xsl:value-of select="../nhm_denominator"/></mn>
        </mfrac>
      </math>
    </nhm_blank_value>
  </xsl:template>   

</xsl:stylesheet>

This will pull the right numerator and denominator values from the original XML rather than hard-coding 14 and 25. When run on your sample XML it produces the correct output:

<resprocessing>
  <respcondition title="Correct" continue="No">
    <conditionvar>
      <varequal respident="Response_0">
        <nhm_blank_name>Answer:</nhm_blank_name>
        <nhm_blank_value>
          <math xmlns="http://www.w3.org/1998/Math/MathML">
            <mfrac>
              <mn>14</mn>
              <mn>25</mn>
            </mfrac>
          </math>
        </nhm_blank_value>
        <nhm_allow_multiples>No</nhm_allow_multiples>
      </varequal>
    </conditionvar>
  </respcondition>
</resprocessing>
Ian Roberts
  • 120,891
  • 16
  • 170
  • 183
  • Thats awesome. But can I add pass param value while replacing the numerator node? Because this param value will be populated from a java program. – jaykumarark Feb 22 '13 at 10:51
  • @jaykumarark do you mean a parameter containing the whole replacement fragment or just the numerator/denominator values? – Ian Roberts Feb 22 '13 at 10:54
  • I mean the parameter containing the fragment. The param will receive the mathml value from a java program. I want to place the param value under the `` node – jaykumarark Feb 22 '13 at 10:56
  • 1
    @jaykumarark the answer depends on which XSLT processor you're using, different processors have different ways to pass in a parameter that is a node set. [This answer](http://stackoverflow.com/a/9113567/592139) shows how to do it with Saxon, other processors may be different. Once you do have a suitable parameter value then it's a simple case of ``. – Ian Roberts Feb 22 '13 at 11:04
  • I can pass parameters. But Im talking using them in the xslt. Is this syntax correct? ` ` But when I do this, it is evaluating the mathml and placing the values directly. It is not placing the mathml nodes under that element. – jaykumarark Feb 22 '13 at 11:07
  • 1
    @jaykumarark indeed - `copy-of` copies the nodes directly, whereas `value-of` gives you the string value of the node set (if it's a set of elements that means the concatenation of all the descendant text nodes of the first element in the node set). – Ian Roberts Feb 22 '13 at 11:13