【问题标题】:Add a xml node through xslt or C# code通过 xslt 或 C# 代码添加 xml 节点
【发布时间】:2012-08-03 07:26:51
【问题描述】:

我有一个输入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>

“status”的值在所有节点中都是“Single”....我知道如何通过c#代码添加这个静态文本“Single”....但是,我不知道如何添加通过 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);
        }

    }
}

非常感谢您的帮助....

【问题讨论】:

  • 您肯定想为此使用 XSLT 吗?它看起来像一个非常简单的转换,代码很容易在代码中完成。
  • 你可以参考我的answer to your question。
  • @Nirav:是的,这更好——尽管我认为值得从 all i> 你的答案。 (这真的没必要,而且看起来你只是渴望代表......)
  • @Nirav:谢谢你的帮助......
  • @JonSkeet:我绝对需要使用 xslt....我的代码应该可以工作....还是谢谢....

标签: c# asp.net xml xslt


【解决方案1】:

您的 XSLT 存在几个问题。首先,这个表达式是不正确的

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

这将选择元素 Single 的值,该值在您的输入 XML 中不存在。您实际上想要输出文字值 'Single'

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

或者更确切地说,您可以“按原样”输出整个元素

<status>Single</status>

其次,您似乎想要将 status 添加为 employee 元素的最后一个元素。在这种情况下,您需要一个模板来匹配 employee 元素,该模板复制所有现有元素,然后添加新的 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>

(注意,我已经删除了对扩展函数的引用,因为我自己的 PC 上没有这些)。

【讨论】:

    【解决方案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 的唯一方式 :)

    【讨论】:

      【解决方案3】:

      你可以用 linq to xml 做:

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

      【讨论】:

        【解决方案4】:

        怎么样

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多