3

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">

3 Answers 3

2

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>
Sign up to request clarification or add additional context in comments.

5 Comments

Didn't work for me... your template produced this: <?xml version="1.0" encoding="UTF-8"?> <Component Win64="yes">cmp25217AE65B163B199EDDA7F29198730A{DEB29383-8BF1-4FD0-830B-DF8639F4069A}</Component> <Component Win64="yes">cmp93E1B1FFA5A62A43251E23BD65FBAA66{76E8B8CE-835D-498E-9330-CE940C9510BF}</Component> <Component Win64="yes">cmp3D7B898C57056B0E87C3A964112BB9D6{3BA9A892-C44F-4B2E-B0B9-B732120D35DB}</Component>
@SteveH. - What processor are you using? Did you have any other templates in your XSLT? It worked fine for me. (+1)
That output was from XMLSpy. Maybe Saxon would be different, I could try with that.
@SteveH: I was assuming you just needed the XSLT fragment, as you didn't supply the complete well-formed input Xml document. I have added a complete XSLT example that doesn't really show anything new; it just has the usual copying template that I assumed you'd have anyway. With this new code sample, you have a complete test case; for me it works like this with MSXML tools. Sorry for not stating this explicitly.
Thanks for sharing your expertise! Great implementation.
0

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>

Comments

-1

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>

1 Comment

What processor are you using? Adding attributes when using xsl:copy should work fine.

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.