XDocument 中两个具有不同前缀的相同命名空间

Two identical namespaces with dirfferent prefixes in XDocument

因此,我尝试使用下一个代码创建 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" 属性的工作簿元素?

我经常这样做

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);
        }
    }
}

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 解析器都不应该关心两个文档之间的差异。