2012-08-03 87 views
0

我有一个输入XML如下添加XML节点,通过XSLT或C#代码

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

,我需要输出XML作为

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

的 “状态” 的值是 “单次”在所有的节点....我知道如何通过C#代码添加这个静态文本“单”....但是,我不知道如何通过xslt在xml中添加节点“状态”....当我尝试,它被添加到节点“firstname”下方,而不是在所示的预期位置....请帮助我如何实现这一点....我使用的xslt和C#代码是,

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

    } 
} 

你的帮助是极大的赞赏....

+1

您是否确实*想为此使用XSLT?它看起来像一个非常简单的转换,代码中的代码很容易完成。 – 2012-08-03 07:38:16

+0

你可以参考我的[回答你的问题](http://stackoverflow.com/questions/11774789/update-xml-file-by-calling-a-c-sharp-function-in-xslt/11776843#11776843)。 – CSharp 2012-08-03 07:41:36

+0

@Nirav:是的,那更好 - 尽管我认为从*全部*您的答案中删除“请标记ACCEPT或+1,如果它对您有用”。 (这真的没有必要,看起来像你只是绝望的代表...) – 2012-08-03 07:47:17

回答

1

有修改XML的唯一方式是你的XSLT的一些问题。首先,这种表达是不正确

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

这将选择元素,这并不在你的输入XML存在的价值。实际上,你要输出的文字值“单​​”

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

或者说,你可以只输出整个元素“原样”

<status>Single</status> 

其次,它看起来像要要添加状态作为员工元素的最后一个元素。在这种情况下,你需要一个模板的员工元素,它会将所有现有元素匹配,然后只是增加了新的状态元素

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

以下是完整的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> 

当适用于您的XML,下面是输出

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

(注意,我删除对扩展功能的引用,因为我的电脑上没有这些功能)。

0

如何

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

你可以使用LINQ做到xml:

var document = XDocument.Parse(xml); 

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

个人认为我认为使用XSLT对此是矫枉过正。我只想用:

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

当然,如果你有其他原因使用XSLT,那很好 - 只是不认为这是在.NET :)