0

We have a current system that outputs an XML file which is in the following format:

<ResultSet rowCount="2">
    <Row>
     <Entry>83708</Entry>
     <mark>L24653338N1</mark>
     <Processed>NO</Processed>
    </Row>
    <Row>
     <Entry>99999</Entry>
     <mark>L24653338N1</mark>
     <Processed>YES</Processed>
    </Row>
</ResultSet>

I need to transform into:

<ResultSet rowCount="2">
    <Row Processed="NO">
     <Entry>83708</Entry>
     <mark>L24653338N1</mark>
     <Processed>NO</Processed>
    </Row>
    <Row Processed="YES">
     <Entry>99999</Entry>
     <mark>L24653338N1</mark>
     <Processed>YES</Processed>
    </Row>
</ResultSet>

Does someone know how this can be done using .XSL?

Here is what I have done:

</xsl:template>
    <xsl:template name="transform">
        <Row>
        <xsl:if test="$linecount&gt;0">
            <xsl:for-each       select="/Msg/Body/Payload[./@Role='S']/Msg/Body/Payload[./@sql]/SqlResult/ResultSet/Row">
                <xsl:attribute name="pos"><xsl:value-of select="position()"/></xsl:attribute>
                <Entry>
                    <xsl:value-of select="./Entry"/>
                </Entry>
                <mark>
                    <xsl:value-of select="./mark"/>
                </mark>
                <Proccessed>
                    <xsl:value-of select="./Proccessed"/>
                </Proccessed>
            </xsl:for-each>
        </xsl:if>
    </Row>
</xsl:template>
4
  • 2
    "Does someone know how this can be done using .XSL?" Yes, there are plenty of folks here who know how to that (hint: it's an XSLT beginner's task) . Are you looking for help in doing this yourself - or do you just expect someone to do your work for you? Commented Feb 17, 2015 at 1:02
  • 1
    On SO, the community expects that people show research effort before asking a question. So please at least show us what you've tried. Commented Feb 17, 2015 at 1:13
  • Here is what I have done just not sure how to take the element and place it as an attribute of Row. I know it is a beginner's task. I am new to xsl so please excuse the simple question. I have seen examples that will convert all elements into the attribute but cant seem to get it to work. Commented Feb 17, 2015 at 1:31
  • I'd suggest you start with an identity transform template. Then add a template matching Row and make it add a Processed attribute to the Row and apply templates to its children. Commented Feb 17, 2015 at 1:58

1 Answer 1

1

In tasks such as these, where you are only making changing to part of the XML, the usual approach is to start with the Identity Transform

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

On its own it will copy all the nodes and attributes as-is, so you only need to write templates for the things you wish to change. In your case you are adding a new Processed attribute onto the Row element. This means you only need a template that matches the Row element that then adds this attribute, like so

<xsl:template match="Row">
    <Row Processed="{Processed}">
        <xsl:apply-templates select="@*|node()"/>
    </Row>
</xsl:template>

Notice the use of Attribute Value Templates in the attribute you are creating. The curly braces {} indicate an expression to be evalualted, not output literally, and so the value of the attribute will actually be the value of the Processed element.

Try this XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="Row">
        <Row Processed="{Processed}">
            <xsl:apply-templates select="@*|node()"/>
        </Row>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Note that you call also create attributes with xsl:attribute. For example

<xsl:template match="Row">
    <Row>
        <xsl:attribute name="Processed">
            <xsl:value-of select="Processed" />
        </xsl:attribute>
        <xsl:apply-templates select="@*|node()"/>
    </Row>
</xsl:template>

But as you can see, this is more verbose, so Attribute Value Templates are preferred where possible.

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

Comments

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.