在XDocument中有两个相同的名称空间,带有不同的前缀

时间:2017-01-30 07:34:44

标签: c# xml linq-to-xml

所以,我尝试用下一个代码创建Xml文档:

XNamespace spr1 = "urn:schemas-microsoft-com:office:spreadsheet";
XNamespace ex = "urn:schemas-microsoft-com:office:excel";
XNamespace spr2 = "urn:schemas-microsoft-com:office:spreadsheet";
XNamespace rec = "http://www.w3.org/TR/REC-html40";

var xworkbook = new XElement(spr1 + "Workbook");

xworkbook.Add(new XAttribute(XNamespace.Xmlns + "x", ex));
xworkbook.Add(new XAttribute(XNamespace.Xmlns +"ss", spr2));
xworkbook.Add(new XAttribute(XNamespace.Xmlns + "html", rec));

此代码生成下一个xml:

<ss:Workbook xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">
    <!--Xml body-->
</ss:Workbook>

但我希望如此:

 <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
 </Workbook>

如何构建没有“ss”前缀和所需“xmlns”属性的Workbook元素?

2 个答案:

答案 0 :(得分:0)

我通常这样做

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
                "<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"" +
                     " xmlns:x=\"urn:schemas-microsoft-com:office:excel\"" +
                     " xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"" +
                     " xmlns:html=\"http://www.w3.org/TR/REC-html40\">" +
                "</Workbook>";

            XDocument doc = XDocument.Parse(xml);
            XElement workbook = (XElement)doc.FirstNode;
            XNamespace ssNs = workbook.GetNamespaceOfPrefix("ss");

            XElement worksheet = new XElement(ssNs + "Worksheet");
            workbook.Add(worksheet);
        }
    }
}

答案 1 :(得分:0)

LINQ to XML使用最接近的名称空间前缀,因为它以从当前元素到根的相反顺序查看所有属性。因此,如果您在结尾处显式添加默认命名空间,那么Workbook将使用该命名空间而不是ss前缀。

XNamespace ss = "urn:schemas-microsoft-com:office:spreadsheet";
XNamespace ex = "urn:schemas-microsoft-com:office:excel";
XNamespace html = "http://www.w3.org/TR/REC-html40";

var workbook = new XElement(
    ss + "Workbook",
    new XAttribute(XNamespace.Xmlns + "x", ex),
    new XAttribute(XNamespace.Xmlns + "ss", ss),
    new XAttribute(XNamespace.Xmlns + "html", html),
    new XAttribute("xmlns", ss)
);

这为您提供了以下XML:

<Workbook xmlns:x="urn:schemas-microsoft-com:office:excel" 
          xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"              
          xmlns:html="http://www.w3.org/TR/REC-html40" 
          xmlns="urn:schemas-microsoft-com:office:spreadsheet" />

如评论中所述,您问题中的两个文档在语义上是相同的。任何XML解析器都不应该关心这两个文档之间的区别。