KimmyG
KimmyG

Reputation: 43

modify child node(s) based on value of another child node

I have the XML below. I would like to process each fields element, and based on the value of elem3, do various things with the remaining elements:
Case1: remove elem1, modify elem2 to a different value
Case2: add elem5, modify elem1 to a different value

I may have various child nodes under each element, so I cannot rely on the names being fixed as elem1 and elem2 always.

<Sample>
  <fields>
    <elem1>Something1</elem1>
    <elem2>SomethingElse1</elem2>
    <elem3>type1</elem3>
  </fields>
</Sample>
<Sample>
  <fields>
    <elem1>Something2</elem1>
    <elem2>SomethingElse2</elem2>
    <elem3>type2</elem3>
    <elem4>sss</elem4>
  </fields>
</Sample>
<Sample>
  <fields>
    <elem1>Something3</elem1>
    <elem2>SomethingElse3</elem2>
    <elem3>type3</elem3>
  </fields>
</Sample>

I've got as far as being able to identify the field elements I want to do something with as below:

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

    <xsl:template match="fields[elem3='type1']">
    </xsl:template>

    <xsl:template match="fields[elem3='type2']">
    </xsl:template>

</xsl:stylesheet>

But now I'm hitting a wall when trying to figure out what goes into the individual templates to do as I want to.

Upvotes: 1

Views: 981

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117102

You can be more specific in matching the nodes you want to affect, e.g.:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<!-- suppress -->
<xsl:template match="elem1[../elem3='type1']"/>

<!-- modify value -->
<xsl:template match="elem2[../elem3='type1']/text()">
    <xsl:value-of select="'New Value'"/>
</xsl:template>

<!-- add elem -->
<xsl:template match="fields[elem3='type2']">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <elem5/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

However, I am not sure what you mean by:

I cannot rely on the names being fixed as elem1 and elem2 always.

Well then, what can you rely on?

Upvotes: 1

Related Questions