0

我有一个输入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”....但是,我不知道如何添加节点“status” “通过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);
        }

    }
}

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

4

4 回答 4

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的唯一方法 :)

于 2012-08-03T07:38:59.367 回答
2

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

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

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

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

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

于 2012-08-03T07:42:13.193 回答
1

您可以使用 linq to xml:

    var document = XDocument.Parse(xml);

    foreach (var element in document.Root.Elements("employee"))
    {
        element.Add(new XElement("status", "Single"));
    }
于 2012-08-03T07:38:11.293 回答
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>
于 2012-08-03T07:36:59.913 回答