2012-08-03 60 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 :)