Reputation: 31
If I have an XML that looks like this:
<Component Id="cmp25217AE65B163B199EDDA7F29198730A" Guid="{DEB29383-8BF1-4FD0-830B-DF8639F4069A}">
<Component Id="cmp93E1B1FFA5A62A43251E23BD65FBAA66" Guid="{76E8B8CE-835D-498E-9330-CE940C9510BF}">
<Component Id="cmp3D7B898C57056B0E87C3A964112BB9D6" Guid="{3BA9A892-C44F-4B2E-B0B9-B732120D35DB}">
How do I us XSLT to append 'Win64="yes"' to the end of each element like this:
<Component Id="cmp25217AE65B163B199EDDA7F29198730A" Guid="{DEB29383-8BF1-4FD0-830B-DF8639F4069A}" Win64="yes">
<Component Id="cmp93E1B1FFA5A62A43251E23BD65FBAA66" Guid="{76E8B8CE-835D-498E-9330-CE940C9510BF}" Win64="yes">
<Component Id="cmp3D7B898C57056B0E87C3A964112BB9D6" Guid="{3BA9A892-C44F-4B2E-B0B9-B732120D35DB}" Win64="yes">
Upvotes: 3
Views: 276
Reputation: 20731
You can use the <xsl:attribute>
element and apply it directly to (inside) the <xsl:copy>
element:
<xsl:template match="Component">
<xsl:copy>
<xsl:attribute name="Win64">yes</xsl:attribute>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
Update: Embedded in an XSLT that otherwise copies the Xml contents, this looks like this:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Component">
<xsl:copy>
<xsl:attribute name="Win64">yes</xsl:attribute>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Update 2: This assumes you only want to add Win64="yes"
to <Component>
elements. If this is not the case, you will have to adapt the XPath expression of the match
attribute in the template that inserts your additional attribute.
Update 3: Well-formed input and output documents:
I assume this as the input document:
<?xml version="1.0" encoding="UTF-8"?>
<xml>
<Component Id="cmp25217AE65B163B199EDDA7F29198730A" Guid="{DEB29383-8BF1-4FD0-830B-DF8639F4069A}"/>
<Component Id="cmp93E1B1FFA5A62A43251E23BD65FBAA66" Guid="{76E8B8CE-835D-498E-9330-CE940C9510BF}"/>
<Component Id="cmp3D7B898C57056B0E87C3A964112BB9D6" Guid="{3BA9A892-C44F-4B2E-B0B9-B732120D35DB}"/>
</xml>
Then, the output of the aforementioned XSLT looks like this:
<?xml version="1.0" encoding="utf-8"?>
<xml>
<Component Win64="yes" Id="cmp25217AE65B163B199EDDA7F29198730A" Guid="{DEB29383-8BF1-4FD0-830B-DF8639F4069A}" />
<Component Win64="yes" Id="cmp93E1B1FFA5A62A43251E23BD65FBAA66" Guid="{76E8B8CE-835D-498E-9330-CE940C9510BF}" />
<Component Win64="yes" Id="cmp3D7B898C57056B0E87C3A964112BB9D6" Guid="{3BA9A892-C44F-4B2E-B0B9-B732120D35DB}" />
</xml>
Upvotes: 2
Reputation: 52858
This stylesheet will add the attribute to all elements like you requested. Note that the position of the attribute might not be at the end, but that shouldn't matter.
XML Input (well-formed)
<doc>
<Component Id="cmp25217AE65B163B199EDDA7F29198730A" Guid="{DEB29383-8BF1-4FD0-830B-DF8639F4069A}"/>
<Component Id="cmp93E1B1FFA5A62A43251E23BD65FBAA66" Guid="{76E8B8CE-835D-498E-9330-CE940C9510BF}"/>
<Component Id="cmp3D7B898C57056B0E87C3A964112BB9D6" Guid="{3BA9A892-C44F-4B2E-B0B9-B732120D35DB}"/>
</doc>
XSLT 1.0 (tested with Xalan and Saxon 6.5.5)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="text()|comment()|processing-instruction()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:attribute name="Win64">yes</xsl:attribute>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output
<doc Win64="yes">
<Component Win64="yes" Id="cmp25217AE65B163B199EDDA7F29198730A" Guid="{DEB29383-8BF1-4FD0-830B-DF8639F4069A}"/>
<Component Win64="yes" Id="cmp93E1B1FFA5A62A43251E23BD65FBAA66" Guid="{76E8B8CE-835D-498E-9330-CE940C9510BF}"/>
<Component Win64="yes" Id="cmp3D7B898C57056B0E87C3A964112BB9D6" Guid="{3BA9A892-C44F-4B2E-B0B9-B732120D35DB}"/>
</doc>
Upvotes: 0
Reputation: 6947
Unfortunately, you can't use <xsl:copy>
and add more attributes. I did it like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/root">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="Component">
<xsl:element name="Component">
<xsl:attribute name="Id" select="@Id"/>
<xsl:attribute name="Guid" select="@Guid"/>
<xsl:attribute name="Win64" select="'yes'"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Upvotes: -1