2012-08-02 49 views
0

我在我的网站项目中有一个xml文件和一个xslt文件。通过调用xslt中的C#函数更新xml文件

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调用C#功能修改xml文件中的值....我通过ac#代码在每个firstname前添加一个文本(称为“Mr.”)....添加后,它将输出t作为响应,但是原始的xml没有被修改。我想,要反映在XML文件....

XML输出需要:

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

此外,作为下一步,我需要添加另一个节点的XML文件(比如年龄)通过另一个c#函数....请注意,应该从我的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> 
+0

可能的重复[通过在xslt中调用C#函数来改变xml文件](http://stackoverflow.com/questions/11772063/alter-xml-file-by-calling-ac-sharp-function-in-xslt ) – 2012-08-02 12:35:56

回答

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

+0

嗨,我得到一个响应作为根元素失踪....我知道这很简单,你能告诉我我要添加的行吗? – 2012-08-02 09:53:21

+0

嗨破折号,我必须使用xslt ....所以,第一个答案是好的....但是,执行它时,它说,“根元件失踪”....请告诉我如何清除这个问题? – 2012-08-02 10:01:27

+0

是的;你需要改变你的XSLT。我用示例XSLT更新了这个问题 - 这只是一个例子,所以它可能不完美。但是,您的方法有一定的局限性,因此您可能会发现DOM方法更有用。 – dash 2012-08-02 10:01:42

0

请参考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> 

希望这会帮助你...