Start with the identity transform, which transforms any XML document into itself.
The identity transform is a simple machine: given a tree, it copies every node it finds recursively. You're going to override its behavior for one specific node - the myagenda
element - which it's going to copy in a different way.
To do this, add a template that matches the element that you want to update and duplicates it. In your case:
<xsl:template match="myagenda">
<xsl:copy-of select=".">
<xsl:apply-templates select="node() | @*"/>
</xsl:copy-of>
</xsl:template>
You might think, "wait isn't that the identity transform?" It is, but it's not going to stay that way.
Now decide on how you're going to get the new contact information into the transform. There are basically two ways: read it from a separate XML document using the document
function, or pass the values into the transform using parameters. Let's assume that you're using parameters; in this case, you'd add the following to the top of your XSLT (right after the xsl:output
element):
<xsl:param name="contactName"/>
<xsl:param name="contactPhone"/>
Now, instead of transforming myagenda
into a copy of itself, you want to transform it into a copy of itself that has a new contact
in it. So modify the template to do this:
<xsl:template match="myagenda">
<xsl:copy-of select=".">
<xsl:apply-templates select="node() | @*"/>
<contact>
<name><xsl:value-of select="$contactName"/></name>
<phone><xsl:value-of select="$contactPhone"/></phone>
</contact>
</xsl:copy-of>
</xsl:template>
If you wanted to get the name and phone out of a separate XML document in the file system, you'd start the XSLT with something like this:
<xsl:variable name="contact" value="document('contact.xml')"/>
<xsl:variable name="contactName" value="$contact/*/name[1]'/>
<xsl:variable name="contactPhone" value=$contact/*/phone[1]'>
That reads in contact.xml
and finds the first name
and phone
element under the top-level element (using *
in the pattern means that you don't care what the top-level element's name is).