0

I have an input xml as follows,

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
<root>
  <employee>
    <firstname>Kaushal</firstname>
    <lastname>Parik</lastname>
  </employee>
  <employee>
    <firstname>Abhishek</firstname>
    <lastname>Swarnkar</lastname>
  </employee>
</root>

and I need output xml as

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
<root>
  <employee>
    <firstname>Kaushal</firstname>
    <lastname>Parik</lastname>
    <status>Single</status>
  </employee>
  <employee>
    <firstname>Abhishek</firstname>
    <lastname>Swarnkar</lastname>
    <status>Single</status>
  </employee>
</root>

The value of "status" is "Single" in all the nodes.... I know how to add this static text "Single" through c# code.... But, I don't know how to add the node "status" in xml through xslt.... When I try, it gets added below the node "firstname" and not in the expected place as shown.... Please help me how can i achieve this.... The xslt and C# code used by me are,

XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
            xmlns:myUtils="pda:MyUtils">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="employee/firstname">
    <xsl:element name="firstname">
      <xsl:value-of select="myUtils:FormatName(.)" />
    </xsl:element>
    <xsl:element name ="status">
      <xsl:value-of select ="Single"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

aspx.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.IO;

public partial class nirav : System.Web.UI.Page
{
    public class MyXslExtension
    {
        public string FormatName(string name)
        {
            return "Mr. " + name;
        }
        public int GetAge(string name)
        {
            int age = name.Count();
            return age;
        }
    }  
    protected void Page_Load(object sender, EventArgs e)
    {
        string outputpath = "nirav.xml";
        XsltArgumentList arguments = new XsltArgumentList();
        arguments.AddExtensionObject("pda:MyUtils", new MyXslExtension());
        using (StreamWriter writer = new StreamWriter(outputpath))
        {
            XslCompiledTransform transform = new XslCompiledTransform();
            transform.Load("http://localhost:4329/XsltTransform/nirav.xslt");
            transform.Transform("http://localhost:4329/XsltTransform/nirav.xml", arguments, writer);
        }

    }
}

Your help is greatly appreciated....

5
  • 1
    Do you definitely want to use XSLT for this? It looks like a really simple transformation which code be done very easily in code. Commented Aug 3, 2012 at 7:38
  • You can refer my answer to your question. Commented Aug 3, 2012 at 7:41
  • @Nirav: Yes, that's better - although I think it would be worth removing the "Please mark ACCEPT or +1 if it is useful to you...." from all your answers. (It's really unnecessary, and looks like you're just desperate for rep...) Commented Aug 3, 2012 at 7:47
  • @JonSkeet: I definitely need to use xslt.... This is not really my project.... I am just giving a sample similar to my project in order to give a clear picture of how my code should work.... Thanks anyway.... Commented Aug 3, 2012 at 9:19
  • @NivethanRajendran: Okay - then my answer won't be useful to you, but I'll leave it up in case it helps future readers. Commented Aug 3, 2012 at 9:19

4 Answers 4

2

There are a couple of issues with your XSLT. Firstly, this expression is incorrect

<xsl:value-of select="Single"/>

This will select the value of the element Single, which does not exist in your input XML. You actually want to output the literal value 'Single'

<xsl:value-of select="'Single'"/>

Or rather, you could just output the whole element 'as-is'

<status>Single</status>

Secondly, it looks like you want to want to add the status as the last element of the employee element. In which case, you need a template to match the employee element, which copies all existing elements, and then just adds the new status element

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

Here is the full XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
   <xsl:output method="xml" indent="yes"/>

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

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

When applied to your XML, the following is output

<root>
   <employee>
      <firstname>Kaushal</firstname>
      <lastname>Parik</lastname>
      <status>Single</status>
   </employee>
   <employee>
      <firstname>Abhishek</firstname>
      <lastname>Swarnkar</lastname>
      <status>Single</status>
   </employee>
</root>

(Note, I've removed the reference to the extension functions, because I don't have those myself on my PC).

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

Comments

2

Personally I think using XSLT is overkill for this. I would just use:

XDocument doc = XDocument.Load("http://localhost:4329/XsltTransform/nirav.xml");
foreach (var employee in doc.Descendants("employee"))
{
    employee.Add(new XElement("status", "Single"));
}
doc.Save(outputPath);

Of course if you have other reasons for using XSLT, that's fine - just don't think it's the only way of modifying XML in .NET :)

Comments

1

You can do with linq to xml:

    var document = XDocument.Parse(xml);

    foreach (var element in document.Root.Elements("employee"))
    {
        element.Add(new XElement("status", "Single"));
    }

Comments

0

How about

<root>
    <xsl:for-each select="\\root\employee">
        <employee>
            <xsl:copy-of select="firstname"/>
            <xsl:copy-of select="lastname"/>
            <status>Single</status>
        </employee>
    </xsl:for-each>
</root>

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.