0

I have a xml file and an xslt file in my website project.

xml file:

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

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:Concat="urn:XslSample">
  <xsl:output method="html" indent="yes"/>
  <xsl:template match="root">
      <xsl:for-each select="employee">
        <![CDATA[Concatenated name is ]]>
            <xsl:value-of select="Concat:GetFullName(firstname,lastname)"/>
            <xsl:value-of select="age"/>
        <br />
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

aspx.cs:

using System;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Xml;
using System.IO;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            MemoryStream objStream = new MemoryStream();
            StreamWriter objWriter = new StreamWriter(objStream, System.Text.Encoding.UTF8);

            XPathDocument doc = new XPathDocument(Server.MapPath("XMLFile.xml"));
            XslCompiledTransform trans = new XslCompiledTransform();
            trans.Load(Server.MapPath("XSLTFile.xslt"));

            //create the XslArgumentList and new BookUtils object
            XsltArgumentList argList = new XsltArgumentList();

            Concat objUtil = new Concat();

            //this tells the argumentlist about BookUtils
            argList.AddExtensionObject("urn:XslSample", objUtil);

            //new XPathNavigator
            XPathNavigator nav = doc.CreateNavigator();

            //do the transform
            trans.Transform(nav, argList, objWriter);
            //objWriter.Flush();
            objStream.Position = 0;
            StreamReader oReader = new StreamReader(objStream);
            string strResult = oReader.ReadToEnd();
            //objWriter.Close();
            //oReader.Close();
            Response.Write(strResult);
        }
        catch (Exception Ex)
        { Response.Write(Ex.Message); }
    }
}

public class Concat
{
    public Concat()
    { }

    public string GetFullName(string firstname, string lastname)
    { return "Mr." + firstname; }
}

When I run the site, I need to call a c# function from xslt and alter the values in xml file.... I am adding a text (say "Mr.") in front of every firstname through a c# code.... After adding, it writes the output as a response, but the original xml is not modified. I want that to be reflected in the xml file....

xml output needed:

<root>
  <employee>
    <firstname>Mr.Kaushal</firstname>
    <lastname>Parik</lastname>
  </employee>
  <employee>
    <firstname>Mr.Abhishek</firstname>
    <lastname>Swarnkar</lastname>
  </employee>
</root>

Also, as a next step, I need to add another node in the xml file (say age) through another c# function.... Please note that the c# function should be called from my xslt file.... Can anyone help me with a simple code for this????

Final xml required:

<root>
  <employee>
    <firstname>Mr.Kaushal</firstname>
    <lastname>Parik</lastname>
    <age>34</age>
  </employee>
  <employee>
    <firstname>Mr.Abhishek</firstname>
    <lastname>Swarnkar</lastname>
    <age>30</age>
  </employee>
</root>
1

2 Answers 2

1

You could consider using the XmlDocument class here;

For example, you actually have the XML you want in the stream output from your XslTransform:

XmlDocument resultDocument = new XmlDocument();
resultDocument.Load(objStream);
resultDocument.Save(Server.MapPath("XMLFile.xml"));

EDIT. You'll also need to change your XSLT for this to work. Something like:

<?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:Concat="urn:XslSample">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
        <root>
            <xsl:apply-templates select="/root/employee" />
        </root>

  </xsl:template>

    <xsl:template match="employee">
        <employee>
            <firstname>Mr. <xsl:value-of select="./firstname"/></firstname>
            <lastname><xsl:value-of select="./lastname"/></lastname>
            <age>24</age>
        </employee>
    </xsl:template>

</xsl:stylesheet>

Should work. However, this is probably not the best approach as you need to supply an age per person and you don't seem to be sourcing this from anywhere. I'd recommend the DOM approach.

You also have to be careful here, though; it's conceivable that there might be a read lock on the file if it's being read by another process. If this is a one off exercise I'd consider just doing this prior to deploying your website.

Another alternative is to not use XSLT. In this instance you could also consider simple DOM processing:

XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("XMLFile.xml"));

XmlNodeList employeeNodes = doc.SelectNodes("//employee");

foreach(XmlNode employeeNode in employeeNodes)
{
    employeeNode.SelectSingleNode("./firstname").InnerText = String.Format("Mr. {0}", employeeNode.SelectSingleNode("./firstname").InnerText);
    XmlNode ageNode = doc.CreateElement("age");
    ageNode.InnerText = "3 Billion Years";
    employeeNode.ChildNodes.Add(ageNode0;
}

doc.Save();

I haven't compile checked this code but hopefully the intent is clear. Note that you could also use XDocument if you preferred.

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

10 Comments

Hi, I am getting a response as root element missing.... I know it is simple, can you tell me the line I've to add?
Hi Dash, I have to use xslt.... So, the first answer is ok.... But, when executing it, it says, "Root element missing".... Kindly tell me how to clear this problem?
Yes; you need to alter your XSLT. I've updated the question with a sample XSLT - it is only an example so it might not be perfect. However, your approach has limitations so you might actually find the DOM approach more useful.
You see, I cannot append the "Mr." in xslt itself.... That needs to come from C# code as indicated in my code....
I've included a sample XSLT that should hopefully help.
|
0

Please refer answer of this question for first step of question.

For next step of answer, use following xsl:

<?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:variable name="vQ">Mr. </xsl:variable>
<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="Age">
  <xsl:value-of select="myUtils:AddAge()" />
</xsl:element>
</xsl:template>

<xsl:template match="employee/firstname">
<xsl:element name="firstname">
  <xsl:value-of select="myUtils:FormatName(.)" />
</xsl:element>
</xsl:template>

<xsl:template match="employee">
<xsl:element  name="employee">
  <xsl:apply-templates select="@* | *"/>
  <xsl:element name="Age">
    <xsl:value-of select="myUtils:AddAge()" />
  </xsl:element>
</xsl:element>
</xsl:template>

</xsl:stylesheet>  

And add following function in MyXslExtension class:

public string AddAge()
    {
        return "25";
    }  

You will get the output like this:

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

Hope this will help you....

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.