2016-01-18 5 views
0

Я пытаюсь создать Excel документ XML, как этотСоздание документа XML Excel с помощью XDocument

<?xml version="1.0"?> 
<?mso-application progid="Excel.Sheet"?> 
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
xmlns:o="urn:schemas-microsoft-com:office:office" 
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"> 
<Styles> 
    <Style ss:ID="Default" /></Style> 
</Styles> 
<Worksheet ss:Name="Worksheet Name"> 
    <Table> 
    <Row ss:AutoFitHeight="0"> 
    <Cell> 
    <Data ss:Type="String">Test</Data> 
    </Cell> 
    </Row> 
    </Table> 
</Worksheet> 
</Workbook> 

Мой текущий результат выглядеть следующим образом:

<?xml version="1.0"?> 
<?mso-application progid="Excel.Sheet"?> 
<ss:Workbook 
    xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:o="urn:schemas-microsoft-com:office:office" 
    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"> 
    <Styles xmlns=""> 
    <Style ss:ID="Default" /> 
    </Styles> 
    <Worksheet ss:Name="Worksheet Name" xmlns=""> 
    <Table> 
     <Row ss:AutoFitHeight="0"> 
     <Cell> 
      <Data ss:Type="String">Test</Data> 
     </Cell> 
     </Row> 
    </Table> 
    </Worksheet> 
</ss:Workbook> 

Я попробовал много разных решений без везения. Мне нужно заменить ss: Workbook with Workbook и избавиться от всего xmlns = "".

Мой текущий код выглядит следующим образом (LINQPad):

void Main() 
{ 
    XNamespace ss = "urn:schemas-microsoft-com:office:spreadsheet"; 
    XNamespace ns = "urn:schemas-microsoft-com:office:spreadsheet"; 

    var workbook = new XElement(ns + "Workbook"); 
    workbook.Add(new XAttribute("xmlns", "urn:schemas-microsoft-com:office:spreadsheet")); 
    workbook.Add(new XAttribute(XNamespace.Xmlns + "o", "urn:schemas-microsoft-com:office:office")); 
    workbook.Add(new XAttribute(XNamespace.Xmlns + "x", "urn:schemas-microsoft-com:office:excel")); 
    workbook.Add(new XAttribute(XNamespace.Xmlns + "ss", "urn:schemas-microsoft-com:office:spreadsheet")); 
    workbook.Add(new XAttribute(XNamespace.Xmlns + "html", "http://www.w3.org/TR/REC-html40")); 

    var styles = new XElement("Styles"); 
    workbook.Add(styles); 
    var style = new XElement("Style"); 
    style.Add(new XAttribute(ss + "ID", "Default")); 
    styles.Add(style); 

    var worksheet = new XElement("Worksheet"); 
    worksheet.Add(new XAttribute(ss + "Name", "Worksheet Name")); 
    workbook.Add(worksheet); 

    var table = new XElement("Table"); 
    worksheet.Add(table); 

    var row = new XElement("Row"); 
    row.Add(new XAttribute(ss + "AutoFitHeight", 0)); 
    table.Add(row); 

    var cell = new XElement("Cell"); 
    var data = new XElement("Data"); 
    data.Add(new XAttribute(ss + "Type", "String")); 
    data.Value = "Test"; 
    cell.Add(data); 
    row.Add(cell); 

    var document = new XDocument(new XDeclaration("1.0", "", null)); 
    document.Add(new XProcessingInstruction("mso-application", "progid=\"Excel.Sheet\"")); 
    document.Add(workbook); 

    var sw = new CustomStringWriter(); 
    document.Save(sw); 
    sw.ToString().Dump(); 
    //sw.ToString().Replace("ss:Workbook", "Workbook").Replace("xmlns=\"\"", "").Dump(); 
} 

// Define other methods and classes here 

class CustomStringWriter : StringWriter 
{ 
    public override Encoding Encoding 
    { 
     get 
     { 
      return null; 
     } 
    } 
} 

Любые предложения?

+0

Мое лучшее взломание в настоящий момент - это оставить пространство имен при добавлении элемента «Рабочая книга» и не добавлять пространство имен xmlns. После преобразования документа в строку я вручную добавляю пространство имен xmlns в элемент «Рабочая книга». Это не очень, но это работает. – halvorsen

+0

Это дубликат http://stackoverflow.com/questions/12075157/unable-to-format-xml-for-excel?rq=1, для которого предлагается использовать Open XML. Это не мое предпочтительное решение, хотя ... – halvorsen

ответ

1

Ваша проблема, скорее всего, в том, что вы не поняли, что пространства имен по умолчанию наследуются от родительских элементов. Возьмите этот XML, например:

<parent xmlns="http://namespace.com/uri"> 
    <child /> 
</parent> 

В этом child также имеет пространство имен http://namespace.com/uri.

Итак, причина в том, что ваши Style, Worksheet элементы и т. Д. Имеют xmlns="", потому что вы явно сказали, что у них нет пространства имен.

Вы должны изменить вам создание всех этих элементов, чтобы включить правильное пространство имен, например:

var styles = new XElement(ss + "Styles"); 

Как и в сторону, я бы также отметить, что LINQ к XML поддерживает гораздо более декларативный подход, чем вы» в настоящее время. Вы можете передать содержимое элемента через конструктор. Таким образом, вы можете переписать ваши стили бит:

var styles = new XElement(ss + "Styles", 
    new XElement(ss + "Style", 
     new XAttribute("ID", "Default") 
     ) 
    ); 

См this fiddle для образца фиксированной & переписана в этом стиле.

+0

Я знаю, что пространство имен наследуется, и это причина для завершения с помощью xmlns = "". Предоставление пространства имен разрешает только половину моей проблемы. Теперь я получаю все пространство имен. Я даже не хочу этого в элементе Workbook. Следовательно, ваше решение не работает для меня. Я не большой поклонник декларативного подхода, поэтому я его не использую ;-) Пример кода составлен из фрагментов из более крупного класса. – halvorsen

+0

Если вы имеете в виду префикс, вы не можете удалить их из-за того, как LINQ to XML работает при написании XML. В качестве примера см. [This fiddle] (https://dotnetfiddle.net/cAb189) - простое синтаксическое разбор и запись вашего «обязательного» XML добавит префикс 'ss' ко всем элементам этого пространства имен. Будьте уверены, что эти два семантически идентичны. –

+0

Если вы переупорядочиваете, чтобы разместить пространство имен по умолчанию после дубликата 'ss' префикса, то поиск в пространстве имен LINQ to XML достигнет этого первого и будет использовать его (см. [This fiddle] (https://dotnetfiddle.net/mkhVgW)). Это приближает вас, если вы предпочитаете, как это выглядит. Я могу только подчеркнуть, что все 3 представления являются семантически идентичными. –