通过XSLT或C#代码添加一个xml节点(Add a xml node through xslt o

2019-09-20 16:59发布

我有一个XML输入如下,

<?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 ....当我尝试,它得到的节点下添加‘名字’,而不是在如图所示的预期的地方....请帮助我,我怎么能做到这一点....对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);
        }

    }
}

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

Answer 1:

有您的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>

(请注意,我已经去除了参考扩展功能,因为我没有那些自己我的电脑)。



Answer 2:

个人认为使用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修改XML的唯一途径:)



Answer 3:

怎么样

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


Answer 4:

你可以使用LINQ到XML做:

    var document = XDocument.Parse(xml);

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


文章来源: Add a xml node through xslt or C# code