I want to transform an input xml file using xslt to change the name of a particular element which can appear at different places of the xml tree.
I have an xml like the following,
<catalog>
<cd>
<ost:title>Empire Burlesque</ost:title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>
<ost:name>Columbia<ost:name>
</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
I want to remove all the 'ost:' prefix from all the elements and keep everything else as it is using xslt. An example code will be appreciated.
In your example, you don't seem to have other namespaces than the one you want to remove. So, here is an example of an XSLT stylesheet, which removes all namespaces from elements (not just your ost:).
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- identity template: copy everything as is... -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<!-- ... except for elements,
create a similarly named element without a namespace -->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
It uses the identity transformation to copy everything as-is, but overrides that for elements to create an element with the same local name, but no namespace.
If you want to just remove your ost: namespace, you can include the namespace declaration for that namespace, and change the latter template to match ost:*.
This transformation is most general. It removes all elements and attributes from namespaces that are specified within a global parameter. It also removes all namespace nodes that are one of those namespaces:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:delNs>
<ns>some:namespace1</ns>
<ns>some:namespace3</ns>
</my:delNs>
<xsl:variable name="vdelNS"
select="document('')/*/my:delNs/*"/>
<xsl:template match="*">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="namespace::*[not(.=$vdelNS)]"/>
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template priority="10" match=
"*[namespace-uri()=document('')/*/my:delNs/*]">
<xsl:element name="{local-name()}">
<xsl:copy-of select="namespace::*[not(.=$vdelNS)]"/>
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
<xsl:template match=
"#*[namespace-uri()=document('')/*/my:delNs/*]">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the following XML document (based on the provided, but corrected to be well-formed and extended to contain 3 namespaces and elements and attributes in them):
<catalog xmlns:ost="some:namespace1"
xmlns:x="some:namespace2"
xmlns:y="some:namespace3">
<cd>
<ost:title>Empire Burlesque</ost:title>
<y:artist>Bob Dylan</y:artist>
<country>USA</country>
<company ost:type="big">
<ost:name>Columbia</ost:name>
</company>
<x:price>10.90</x:price>
<year>1985</year>
</cd>
</catalog>
the wanted result is produced:
<catalog xmlns:x="some:namespace2">
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company type="big">
<name>Columbia</name>
</company>
<x:price>10.90</x:price>
<year>1985</year>
</cd>
</catalog>
Explanation:
The first two templates are almost equivalent to the identity rule, but they do not copy namespace nodes for the namespaces specified in <my:delNs>.
The last two templates are for all elements and attributes that belong to a namespace listed under <my:delNs>. Only in these two templates names are actually changed to only local names.
Related
I've fairly recently started learning XSLT after getting to grips with XML and XPath; I'm trying to complete a practice exercise; I think I'm nearly there but I've ran into a problem. So I have the following XML document:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<a>
<b></b>
<b></b>
<b></b>
<b></b>
</a>
</root>
And I'd like to surround the elements with a pair of parent elements (to output the following):
<?xml version="1.0" encoding="UTF-8"?>
<root>
<a>
<b-group>
<b></b>
<b></b>
<b></b>
<b></b>
<b-group>
</a>
Here is my XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="root">
<xsl:element name="root">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="a">
<xsl:element name="a">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="b">
<xsl:element name="b-group">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="b">
<xsl:element name="b">
<xsl:apply-templates select="#*|node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Despite making several other attempts, I'm having difficulty creating the pair of elements that surround the elements; could anyone point me in the right direction of how to do this please?
You need to do this in the template matching a, for example:
<xsl:template match="a">
<a>
<b-group>
<xsl:apply-templates select="b"/>
</b-group>
</a>
</xsl:template>
Additional notes:
Use a literal result element to create an element whose name is known, instead of xsl:element.
Most of your templates do the same thing: create an element with the same name as the one being matched, and apply templates to its children. Thus they could be consolidated into one. A template like this is known as the identity transform template and it is commonly used when most of the document needs to preserved as is, with only a few modifications. This would reduce your entire stylesheet to just:
<xsl:stylesheet version="2.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>
<xsl:template match="a">
<a>
<b-group>
<xsl:apply-templates select="b"/>
</b-group>
</a>
</xsl:template>
</xsl:stylesheet>
I need to find duplicate nodes (identified by ID) and if such nodes exist, then I need to update the id of one of them. Will appreciate if someone can let me know how to do it based on xpath or xsl.
example xml:
<music>
<title id="1"/>
<title id="2"/>
<title id="1"/>
</music>
The first and third node have the same ID. So, the id of the third is changed to '3'. I need to change it to the following:
<music>
<title id="1"/>
<title id="2"/>
<title id="3"/>
</music>
Please try the following template:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="music">
<xsl:copy>
<xsl:for-each select="*">
<xsl:element name="{name()}">
<xsl:attribute name="id">
<xsl:choose>
<xsl:when test="preceding::*/#id=current()/#id">
<xsl:value-of select="generate-id()"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="#id"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Usually, the purpose of an ID is to uniquely identify elements. If so, it is insignificant what the actual ID string is - as long as there are no duplicates.
Therefore, the easiest approach to your problem is to number all title elements consistently, as remarked already by #michael.hor257k. This can be done using either position() or xsl:number.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/music">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="title">
<xsl:copy>
<xsl:attribute name="id">
<xsl:number/>
</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output
<?xml version="1.0" encoding="UTF-8"?>
<music>
<title id="1"/>
<title id="2"/>
<title id="3"/>
</music>
I am working on XSLT, where I need to implement something as follows.
My Source XML sample looks like this.
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>A</title>
<title>B</title>
<title>C</title>
</cd>
</catalog>
Consider there is some key value pair list is there.
Key Value
A Algebra
B Biology
C Chemistry
D Data Analysis
--- ---
---- ---
I need to write an xslt such that for every occurance of key 'A', need to replace with appropriate value.
I also need to mention the list of Key value pairs in the same XSLT.
Sample Output:
<Data>
<Subject>Algebra</Subject>
<Subject>Biology</Subject>
<Subject>Chemistry</Subject>
</Data>
Can any one help me out how to do it.
Thank you.
I. Simple XSLT 1.0 Solution
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</my:codes>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[. = document('')/*/my:codes/*/#key]">
<xsl:value-of select=
"document('')/*/my:codes/*[#key=current()]/#value"/>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<catalog>
<cd>
<title>A</title>
<title>B</title>
<title>C</title>
</cd>
</catalog>
produces the wanted, correct result:
<catalog>
<cd>
<title>Algebra</title>
<title>Biology</title>
<title>Chemistry</title>
</cd>
</catalog>
Explanation:
This is the standard way of including inline XML node as a global element (child element of xsl:stylesheet) that belongs to a (non-empty) namespace, different than the xsl namespace.
II. More efficient XSLT 1.0 solution, using keys:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</my:codes>
<xsl:key name="kCodeByName" match="code" use="#key"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[. = document('')/*/my:codes/*/#key]">
<xsl:variable name="vCur" select="."/>
<xsl:for-each select="document('')">
<xsl:value-of select=
"key('kCodeByName', $vCur)/#value"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the same XML document (above), the same correct, wanted result is produced:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Explanation:
Accessing data via the key() function is typically sub-linear -- often O(1) and is extremely faster than linear search (which is important if the number of nodes to be searched is big).
Accessing a node of one document via an index (xsl:key) while processing a node of another document is possible if the document containing the node to be looked-up is the current document. To access nodes from the other document, its root (or node of interest need to be saved and referenced off a variable.)
III. XSLT 2.0 solution:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vCodes">
<codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</codes>
</xsl:variable>
<xsl:key name="kCodeByName" match="code" use="string(#key)"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[key('kCodeByName', ., $vCodes)]">
<xsl:sequence select=
"key('kCodeByName', ., $vCodes)/#value"/>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the same XML document (above), the same correct, wanted result is produced:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Explanation:
Almost the same as the efficient XSLT 1.0 solution, but:
In XSLT 2.0 a template match pattern can contain a variable reference.
In XSLT 2.0 there is no need for acrobatic tricks manipulating the current and the indexed documents -- the 3rd argument of the key() function is to specify the tree whose index to use.
I have a custom XML schema that is evolving: elements are added, others deleted, and the namespace changes to reflect the new version (e.g., from "http://foo/1.0" to "http://foo/1.1"). I want to write an XSLT that converts XML documents from the old schema to the new one. My first attempt works, but it's verbose and unscalable, and I need help refining it.
Here's a sample document for the 1.0 schema:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo:rootElement xmlns:foo="http://foo/1.0">
<obsolete>something</obsolete>
<stuff>
<alpha>a</alpha>
<beta>b</beta>
</stuff>
</foo:rootElement>
In the 1.1 schema, the "obsolete" element goes away but everything else remains. So the XSLT needs to do two things:
Remove the tag
Change the namespace from http://foo/1.0 to http://foo/1.1
Here's my solution:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:foo1="http://foo/1.0"
xmlns:foo="http://foo/1.1"
exclude-result-prefixes="foo1">
<xsl:output method="xml" standalone="yes" indent="yes"/>
<!-- Remove the "obsolete" tag -->
<xsl:template match="foo1:rootElement/obsolete"/>
<!-- Copy the "alpha" tag -->
<xsl:template match="foo1:rootElement/stuff/alpha">
<alpha>
<xsl:apply-templates/>
</alpha>
</xsl:template>
<!-- Copy the "beta" tag -->
<xsl:template match="foo1:rootElement/stuff/beta">
<beta>
<xsl:apply-templates/>
</beta>
</xsl:template>
<!-- Copy the "stuff" tag -->
<xsl:template match="foo1:rootElement/stuff">
<stuff>
<xsl:apply-templates/>
</stuff>
</xsl:template>
<!-- Copy the "rootElement" tag -->
<xsl:template match="foo1:rootElement">
<foo:rootElement>
<xsl:apply-templates/>
</foo:rootElement>
</xsl:template>
</xsl:stylesheet>
Although this produces the output I want, notice that I have a copying template for every element in the schema: alpha, beta, etc. For complex schemas with hundreds of kinds of elements, I'd have to add hundreds of templates!
I thought I could eliminate this problem by reducing all those copying templates into a single identity transform, like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:foo1="http://foo/1.0"
xmlns:foo="http://foo/1.1"
exclude-result-prefixes="foo1">
<xsl:output method="xml" standalone="yes" indent="yes"/>
<xsl:template match="foo1:rootElement/obsolete"/>
<xsl:template match="node()|#*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="foo1:rootElement/stuff">
<xsl:copy>
<xsl:call-template name="identity"/>
</xsl:copy>
</xsl:template>
<xsl:template match="foo1:rootElement">
<foo:rootElement>
<xsl:apply-templates/>
</foo:rootElement>
</xsl:template>
</xsl:stylesheet>
But it produces:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<foo:rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:foo="http://foo/1.1">
<stuff xmlns:foo="http://foo/1.0">
<stuff>
<alpha>a</alpha>
<beta>b</beta>
</stuff>
</stuff>
</foo:rootElement>
The "stuff" element was copied, which is what I want, but it's wrapped in another "stuff" element, tagged with the old namespace. I don't understand why this is happening. I've tried many ways of fixing this but have been unsuccessful. Any suggestions? Thanks.
This transformation:
<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:param name="pOldNS" select="'http://foo/1.0'"/>
<xsl:param name="pNewNS" select="'http://foo/1.1'"/>
<xsl:template match="/*">
<xsl:element name="{name()}" namespace="{$pNewNS}">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="namespace::*[not(.=$pOldNS)]"/>
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
<xsl:template match="#*">
<xsl:choose>
<xsl:when test="namespace-uri()=$pOldNS">
<xsl:attribute name="{name()}" namespace="{$pNewNS}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="obsolete"/>
</xsl:stylesheet>
when applied on this XML document:
<foo:rootElement xmlns:foo="http://foo/1.0">
<obsolete>something</obsolete>
<stuff>
<alpha x="y" foo:t="z">a</alpha>
<beta>b</beta>
</stuff>
</foo:rootElement>
produces the wanted, correct result (obsolute elements deleted, namespace upgraded, attribute nodes correctly processed, including nodes that were in the old namespace):
<foo:rootElement xmlns:foo="http://foo/1.1">
<stuff>
<alpha x="y" foo:t="z">a</alpha>
<beta>b</beta>
</stuff>
</foo:rootElement>
Main advantages of this solution:
Works correctly when there are attributes, belonging to the old-schema namespace.
General, allows the old and new namespace to be passed as external parameters to the transformation.
While you might want to copy the attributes, elements need to be regenerated in the new namespace. So I'd suggest to do it like this:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foo1="http://foo/1.0">
<xsl:template match="foo1:rootElement/obsolete"/>
<xsl:template match="attribute()">
<xsl:copy/>
</xsl:template>
<xsl:template match="element()">
<xsl:variable name="name" select="local-name()"/>
<xsl:element name="{$name}" namespace="http://foo/1.1">
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
My problem is that in some xml files an element exists and in another it does not.
When the element exists, it's value should be changed. If it does not exists, it should be added.
Here is an example for better understanding:
<root>
<group>
<element1>SomeValue1</element1>
<element2>SomeValue2</element2>
</group>
</root>
Let's say I always want element1, element2 and element3 with the values Changed1, Changed2, Changed3.
It should end up like this:
<root>
<group>
<element1>Changed1</element1>
<element2>Changed2</element2>
<element3>Changed3</element3>
</group>
</root>
What can I do to make it happen?
Thanking you in anticipation
Dennis
I'm not sure if it's the most elegant solution in the world, but I think this would probably do what you're after:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- If the element exists, do what you want to do -->
<xsl:template match="element1">
<xsl:copy>Changed1</xsl:copy>
</xsl:template>
<xsl:template match="element2">
<xsl:copy>Changed2</xsl:copy>
</xsl:template>
<xsl:template match="element3">
<xsl:copy>Changed3</xsl:copy>
</xsl:template>
<!-- If the element doesn't exist, add it -->
<xsl:template match="group">
<xsl:copy>
<xsl:apply-templates/>
<xsl:if test="not(element1)">
<element1>Changed1</element1>
</xsl:if>
<xsl:if test="not(element2)">
<element2>Changed2</element2>
</xsl:if>
<xsl:if test="not(element3)">
<element3>Changed3</element3>
</xsl:if>
</xsl:copy>
</xsl:template>
<!-- Identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Anything which isn't explicitly matched should just copy across untouched.
Of course, if the values are constant (that is, element1, element2 and element3 will always have the same values regardless of whether they're new or updated) then you can have something simpler:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- If the element exists, remove it -->
<xsl:template match="element1 | element2 | element3"/>
<!-- Now put in your preferred elements -->
<xsl:template match="group">
<xsl:copy>
<xsl:apply-templates/>
<element1>Changed1</element1>
<element2>Changed2</element2>
<element3>Changed3</element3>
</xsl:copy>
</xsl:template>
<!-- Identity transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Which essentially removes the original "element" nodes and puts yours in in their place.
Here is a more generic solution. The names of the elements can be specified separately from the code:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:newValues>
<element1>Changed1</element1>
<element2>Changed2</element2>
<element3>Changed3</element3>
</my:newValues>
<xsl:variable name="vElements" select="document('')/*/my:newValues/*"/>
<xsl:template match="*" name="identity" mode="copy">
<xsl:element name="{name()}">
<xsl:copy-of select="namespace::*[not(name()='my' or name()='xsl')]"/>
<xsl:apply-templates select="node()|#*"/>
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:if test="not($vElements[name()=name(current())])">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
<xsl:template match="group">
<xsl:copy>
<xsl:apply-templates select="node()"/>
<xsl:apply-templates select="$vElements" mode="copy"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on the provided XML document:
<root>
<group>
<element1>SomeValue1</element1>
<element2>SomeValue2</element2>
</group>
</root>
the wanted, correct result is produced:
<root>
<group>
<element1>Changed1</element1>
<element2>Changed2</element2>
<element3>Changed3</element3>
</group>
</root>
Note: The seemingly complicated processing that discards the "xsl" anf "my" namespaces is unnecessary when the to-be-modified elements are in their separate document. This code intentionally puts the to-be-modified elements in the same document as the xslt stylesheet for demonstration purposes. In practice, just an <xsl:copy-of select="$vModifiedDoc/*"> will be used.
Your example might be oversimplified. It looks like you can just generate the 3 "changed" values for every element you encounter... so I'm guessing it's a bit more complicated than that in real life.
In any case, if the changed value is not a replacement but actually a modification of the original value, you can probably use a for-each on groups and then generate the 3 elements, where the value of each element is based on an xsl-if element that checks whether the original value exists and uses it if so.
Just for fun, an XSLT 2.0 solution:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vAdd" as="element()*">
<element1>Changed1</element1>
<element2>Changed2</element2>
<element3>Changed3</element3>
</xsl:variable>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="group/*[name()=$vAdd/name()]"/>
<xsl:template match="group/*[last()]" priority="1">
<xsl:next-match/>
<xsl:apply-templates select="$vAdd"/>
</xsl:template>
</xsl:stylesheet>
Output:
<root>
<group>
<element1>Changed1</element1>
<element2>Changed2</element2>
<element3>Changed3</element3>
</group>
</root>