【问题标题】:Update xml file by calling a C# function in xslt通过在 xslt 中调用 C# 函数来更新 xml 文件
【发布时间】:2012-07-31 06:23:52
【问题描述】:

我的网站项目中有一个 xml 文件和一个 xslt 文件。

xml 文件:

<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; }
}

当我运行该站点时,我需要从 xslt 调用 ac# 函数并更改 xml 文件中的值....我通过 ac# 代码在每个名字前面添加一个文本(比如“先生”) ....添加后,它将输出作为响应写入,但原始xml没有被修改。我希望将其反映在 xml 文件中....

需要xml输出:

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

另外,作为下一步,我需要通过另一个 c# 函数在 xml 文件中添加另一个节点(比如年龄)......请注意,应该从我的 xslt 文件中调用 c# 函数......可以有人帮我写一个简单的代码吗????

需要最终的 xml:

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

【问题讨论】:

标签: c# asp.net xml xslt


【解决方案1】:

您可以考虑在这里使用 XmlDocument 类;

例如,您实际上在 XslTransform 的流输出中拥有所需的 XML:

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

编辑。您还需要更改 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="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>

应该可以。但是,这可能不是最好的方法,因为您需要提供每个人的年龄,而且您似乎没有从任何地方采购。我推荐使用 DOM 方法。

不过,您在这里也必须小心;可以想象,如果文件正在被另一个进程读取,则该文件可能存在读锁。如果这是一次性练习,我会考虑在部署您的网站之前这样做。

另一种选择是不使用 XSLT。在这种情况下,您还可以考虑简单的 DOM 处理:

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();

我尚未编译检查此代码,但希望其意图很明确。请注意,如果您愿意,也可以使用XDocument

【讨论】:

  • 嗨,我收到了一个响应,因为缺少根元素...。我知道这很简单,你能告诉我我要添加的行吗?
  • 嗨 Dash,我必须使用 xslt.... 所以,第一个答案是好的....但是,在执行它时,它说,“缺少根元素”....告诉我如何解决这个问题?
  • 是的;您需要更改您的 XSLT。我已经用示例 XSLT 更新了这个问题——它只是一个示例,因此它可能并不完美。但是,您的方法有局限性,因此您实际上可能会发现 DOM 方法更有用。
  • 你看,我不能附加“先生”。在 xslt 本身中......这需要来自我的代码中所示的 C# 代码......
  • 我提供了一个示例 XSLT,希望能有所帮助。
【解决方案2】:

问题的第一步请参考this question的答案。

对于答案的下一步,请使用以下 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>  

并在 MyXslExtension 类中添加以下函数:

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

你会得到这样的输出:

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

希望对你有帮助....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多