Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ2XML将所有命名空间声明移动到根元素_C#_Xml_Namespaces_Xml Namespaces_Xelement - Fatal编程技术网

C# LINQ2XML将所有命名空间声明移动到根元素

C# LINQ2XML将所有命名空间声明移动到根元素,c#,xml,namespaces,xml-namespaces,xelement,C#,Xml,Namespaces,Xml Namespaces,Xelement,这听起来像是一个很多人都会提出的问题,但经过数小时的搜索,我甚至找不到一个解决这个问题的问题 我正在使用LINQ2Xml类生成XML文档。我使用了许多名称空间,节点是动态创建的,因此不能使用nicewxelement(“abc”,newxelement…)格式声明 下面是一个例子: XNamespace ns1 = "scheme://ns1"; XNamespace ns2 = "scheme://ns2"; XNamespace ns3 = "scheme://ns3"; XNamespac

这听起来像是一个很多人都会提出的问题,但经过数小时的搜索,我甚至找不到一个解决这个问题的问题

我正在使用LINQ2Xml类生成XML文档。我使用了许多名称空间,节点是动态创建的,因此不能使用nicewxelement(“abc”,newxelement…)格式声明

下面是一个例子:

XNamespace ns1 = "scheme://ns1";
XNamespace ns2 = "scheme://ns2";
XNamespace ns3 = "scheme://ns3";
XNamespace ns4 = "scheme://ns4";

XElement el1 = new XElement(ns1 + "el1");
XElement el2 = new XElement(ns2 + "el2");
XElement el3 = new XElement(ns3 + "el3");
XElement el4 = new XElement(ns4 + "el4");

XElement el5 = new XElement(ns1 + "el5");
XElement el6 = new XElement(ns1 + "el5");
XElement el7 = new XElement(ns1 + "el5");

el4.Add(el7);
el3.Add(el6);
el2.Add(el5);

el1.Add(el2);
el1.Add(el3);
el1.Add(el4);

XDocument doc = new XDocument(el1);
Debug.Write(doc.ToString());
上述代码生成以下输出:

<el1 xmlns="scheme://ns1">
  <el2 xmlns="scheme://ns2">
    <el5 xmlns="scheme://ns1" />
  </el2>
  <el3 xmlns="scheme://ns3">
    <el5 xmlns="scheme://ns1" />
  </el3>
  <el4 xmlns="scheme://ns4">
    <el5 xmlns="scheme://ns1" />
  </el4>
</el1>

然而,我希望输出更类似于下面的(E&OE),其中所有namesapce声明都位于顶部,而不是每个元素上

<el1 xmlns="scheme://ns1" xmlns:ns2="scheme://ns2" xmlns:ns3="scheme://ns3" xmlns:ns4="scheme://ns4">
    <ns2:el2 >
        <ns1:el5 />
    </ns2:el2>
    ....
</el1>

....
我已经尝试过以下方法,但完全没有区别:

IEnumerable<XAttribute> allNs = doc.Root.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration);
int i = 0;
foreach (string uri in allNs.Select(a => a.Value).Distinct()) {
    string prefix = "ns" + ++i;
    doc.Root.Add(new XAttribute(XNamespace.Xmlns + prefix, uri));
}
Debug.Write(doc.ToString(SaveOptions.OmitDuplicateNamespaces));
IEnumerable allNs=doc.Root.subjects().Attributes()。其中(a=>a.IsNamespaceDeclaration);
int i=0;
foreach(allNs.Select(a=>a.Value.Distinct()中的字符串uri){
字符串前缀=“ns”+++i;
添加(新的XAttribute(XNamespace.Xmlns+前缀,uri));
}
Debug.Write(doc.ToString(SaveOptions.ommitDuplicateNamespaces));
推理:我希望一个文件最多有几十个名称空间,每个名称空间中有几百个元素。每个名称空间的uri可能有50个字符长,我只声明一次名称空间就可以节省数千个字符。此外,它只是看起来更好


有人知道如何做到这一点吗?

将其他名称空间作为属性添加到根元素:

XElement el1 = new XElement(ns1 + "el1", 
    new XAttribute(XNamespace.Xmlns + "ns2", ns2),
    new XAttribute(XNamespace.Xmlns + "ns3", ns3),
    new XAttribute(XNamespace.Xmlns + "ns4", ns4));
输出:

<el1 xmlns:ns2="scheme://ns2" xmlns:ns3="scheme://ns3" xmlns:ns4="scheme://ns4" xmlns="scheme://ns1">
  <ns2:el2>
    <el5 />
  </ns2:el2>
  <ns3:el3>
    <el5 />
  </ns3:el3>
  <ns4:el4>
    <el5 />
  </ns4:el4>
</el1>

谢谢,我以为这就是我在最后一个代码块中所做的。事实证明,xmlns属性只有在序列化之后才能创建。这就是我最终使用的代码(我忘了提到,在编译时我不知道所有的名称空间):IEnumerable allNs=doc.subjects().Select(e=>e.Name.Namespace).Distinct();int i=0;foreach(XNamespace-ns-in-allNs){string prefix=“ns”++i;doc.Root.Add(新的XAttribute(XNamespace.Xmlns+前缀,ns));}