2017-01-30 2 views
0

Таким образом, я пытаюсь создать Xml документ со следующим кодом:Два одинаковых имен с dirfferent префиксов в XDocument

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

ответ

0

LINQ к 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 не должен заботиться о различии между этими двумя документами.

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

Это имеет ту же проблему, что и исходный код OP. – JLRishe

+0

Спасибо за ответ, но это обходное решение. Я проверю ваш ответ, если не найду другого решения. –

+0

Не знаете, почему вы считаете это обходным, поскольку он работает. Пространства имен в сети являются ошибками, и я считаю, что гораздо проще просто анализировать пространства имен, чем пытаться заставить Net Library работать правильно. Кроме того, мой код намного легче понять. С Net-библиотекой вы всегда должны использовать пространство имен по умолчанию последним атрибутом. – jdweng

Смежные вопросы