1

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.

2
  • Note that your input XML example is missing a root element. Commented Apr 6, 2014 at 0:07
  • Update: I cannot rely on element names being elem1, elem2, etc. means that some fields will have children elem1, 2, 3, others 1,3,5, etc. - I cannot know for sure what will be there up front, so I need to be able to keep anything I'm not expressly modifying. Commented Apr 6, 2014 at 17:35

1 Answer 1

1

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?

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you - works like a charm. Didn't thing of selecting elem2[../elem3='type1'] by going through the parent...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.