2015-12-11 4 views
0

Я хочу, чтобы сформировать XML в следующем формате, используя класс XmlWriter в C# -:Как создать следующий Xml с помощью класса XmlWriter в C#?

<?xml version="1.0" ?> 
<root> 
<data> 
    <entry Attrib1="" Attrib2="91.3467" Attrib3="95.3052" Attrib4="6.4722" /> 
    <entry Attrib1="" Attrib2="91.3467" Attrib3="95.3052" Attrib4="6.4722" /> 
</data> 
</root> 

Я новичок в классе XmlWriter и C# в целом, и я пытался писать код для создания файла с выше формата, но эта попытка оказалась неудачной

var xmlWriter = XmlWriter.Create(filename); 
      xmlWriter.WriteStartDocument(); 
      xmlWriter.WriteStartElement("data"); 

      xmlWriter.WriteStartElement("entry"); 
      xmlWriter.WriteAttributeString("attrib1", "value1"); 
      xmlWriter.WriteAttributeString("attrib2", "value2"); 
      xmlWriter.Close(); 

также, название атрибутов может включена недопустимые символы XML, и именно поэтому я прочитал на XMLWriter, потому что кажется, чтобы удалить эти недопустимые символы из имен атрибутов Например, имя типа «это атрибут 1» должно быть сведено к чему-то вроде «this_is_attribute_1» при написании в результирующий XML, как я могу начать создавать такой XML с помощью XmlWriter. Короче строка результирующего XML является чем-то вроде этого

<entry P_B_Pe="" P_E_Pe="91.3467" Custom_Price="95.3052" C_Yield="6.4722" Average_Life="" /> 

ответ

1

Вы почти получили это .. .

var xmlWriter = XmlWriter.Create(filename); 
    xmlWriter.WriteStartDocument(); 
     xmlWriter.WriteStartElement("root"); 
      xmlWriter.WriteStartElement("data"); 
       xmlWriter.WriteStartElement("entry"); 
        xmlWriter.WriteAttributeString("attrib1", "value1"); 
        xmlWriter.WriteAttributeString("attrib2", "value2"); 
       xmlWriter.WriteEndElement(); // entry 
       xmlWriter.WriteStartElement("entry"); 
        xmlWriter.WriteAttributeString("attrib1", "value1"); 
        xmlWriter.WriteAttributeString("attrib2", "value2"); 
       xmlWriter.WriteEndElement(); // entry 
      xmlWriter.WriteEndElement(); // data 
     xmlWriter.WriteEndElement(); // root 
    xmlWriter.WriteEndDocument(); 
xmlWriter.Close(); 

По умолчанию XmlWriter будет кодировать символы, которые обычно не действительны в исходных данных или значениях атрибутов таким образом, что они вернутся, когда вы используете читатель, декодируете XML, но атрибуты и имена элементов должны быть действительны. Если вы хотите обрабатывать недопустимые символы для тех, кто каким-то особым образом, который отличается от того, вы должны будете сделать это самостоятельно в соответствии с правилами независимо вы хотите установить, что-то вроде:

xmlWriter.WriteAttributeString(MyXmlExtensions.EncodeXmlAttributeName("this is normally an invalid attribute name"), "value1"); 

class MyXmlExtensions 
{ 
    public string EncodeXmlAttributeName(string decoded) 
    { 
     // not that you'll likely need to enhance this with whatever rules you want but haven't specified 
     return decoded.Replace(" ", "_"); 
    } 
    public string DecodeXmlAttributeName(string encoded) 
    { 
     // not that you'll likely need to enhance this with whatever rules you want but haven't specified 
     return encoded.Replace("_", " "); 
    } 
} 

Вам также потребуется использовать XmlWriterSettings в вызове XmlWriter.Create, если вы хотите, чтобы результат выглядел красиво (вкладки, несколько строк и т. д.).

+0

эй спасибо за решение например, просто хотел знать, что в .NET нет ничего, что преобразует строку атрибута в допустимое имя атрибута XML, если у меня есть строка, такая как Port. его действительным атрибутом XML должен быть Port_Entry_is. Именно здесь я столкнулся с большой путаницей, я также посмотрел на метод XmlConvert.Encode, но это также не служит мне для этой цели. – AnkitSablok

+0

@AnkitSablok: это правильно. .NET не поддерживает специальную кодировку имен элементов и атрибутов. 'XmlConvert.Encode' - это то, что используется внутри, чтобы кодировать необработанные строковые данные, сбрасываемые в содержимое элемента, а не их имена или атрибуты. Он также может использоваться вызывающими программами, если они генерируют XML вручную и добавляют его с помощью 'XmlWriter.WriteRaw'. Вы можете сделать что-то подобное, но даже «XmlConvert.Encode» не будет работать для имен элементов. – James

+0

Прохладный, это то, что я искал, поэтому мы можем с уверенностью заключить, что формат, в котором требуются имена атрибутов, полностью зависит от ситуации/контекста, в котором генерируется XML? – AnkitSablok

0

Try XML Linq

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      StreamWriter sWriter = new StreamWriter(FILENAME); 
      XmlTextWriter writer = new XmlTextWriter(sWriter); 

      writer.WriteStartDocument(); 
      writer.WriteStartElement("root"); 
      writer.WriteStartElement("data"); 

      double?[] attributes = new double?[] { null, 91.3467, 95.3052, 6.4722 }; 
      XElement entry = new XElement("entry"); 
      int index = 1; 

      foreach (double? attribute in attributes) 
      { 
       if (attribute == null) 
       { 
        entry.Add(new XAttribute("Attrib" + index++.ToString(), "")); 
       } 
       else 
       { 
        entry.Add(new XAttribute("Attrib" + index++.ToString(), attribute)); 
       } 
      } 

      writer.WriteRaw(entry.ToString()); 
      writer.WriteRaw(entry.ToString()); 

      writer.WriteEndElement(); 
      writer.WriteEndElement(); 

      writer.Flush(); 
      writer.Close(); 


     } 
    } 
} 
​ 

делать без каких-либо XML LINQ затем

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

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      StreamWriter sWriter = new StreamWriter(FILENAME); 
      XmlTextWriter writer = new XmlTextWriter(sWriter); 

      writer.WriteStartDocument(); 
      writer.WriteStartElement("root"); 
      writer.WriteStartElement("data"); 
      writer.WriteStartElement("entry"); 

      double?[] attributes = new double?[] { null, 91.3467, 95.3052, 6.4722 }; 
      int index = 1; 
      foreach (double? attribute in attributes) 
      { 
       writer.WriteStartAttribute("Attrib" + index++.ToString()); 
       if (attribute == null) 
       { 
        writer.WriteValue(""); 
       } 
       else 
       { 
        writer.WriteValue(attribute); 
       } 
       writer.WriteEndAttribute(); 

      } 

      writer.WriteEndElement(); 

      writer.WriteStartElement("entry"); 
      attributes = new double?[] { null, 91.3467, 95.3052, 6.4722 }; 
      index = 1; 
      foreach (double? attribute in attributes) 
      { 
       writer.WriteStartAttribute("Attrib" + index++.ToString()); 
       if (attribute == null) 
       { 
        writer.WriteValue(""); 
       } 
       else 
       { 
        writer.WriteValue(attribute); 
       } 
       writer.WriteEndAttribute(); 

      } 

      writer.WriteEndElement(); 

      writer.WriteEndElement(); 
      writer.WriteEndElement(); 

      writer.Flush(); 
      writer.Close(); 


     } 
    } 
} 
​ 
+0

Таким образом, ситуация такова, что у меня есть данные, поступающие из файла или потока, как вам нравится, и Я хочу использовать XmlTextWriter для записи этих данных в XML-результат, у меня есть решение, которое делает то же самое, что вы написали, используя класс XDocument и класс XAttribute, но я не хочу использовать эти конструкции в первую очередь. – AnkitSablok

+0

Измененный код для использования XMLTextWriter. – jdweng

+0

Предположим, что атрибуты XML-записи выглядят примерно так: «имя человека», «возраст человека», то есть атрибуты имеют специальные символы, такие как пробелы, &, »и т. Д., И я хочу эти атрибуты в их допустимом формате при записи полученного xml, так как в результате они должны выглядеть следующим образом: без каких-либо манипуляций с строками, возможно ли это с помощью XmlTextWriter? – AnkitSablok

0

Используйте объект сериализации, то вы не должны иметь объект структура отображения кода

using System.Xml.Serialization; 

... 

[XmlRoot("root")] 
public class Example { 
    [XmlElement("data")] 
    public Entries Entries { get; set; } 
} 

public class Entries : List<List<string>>, IXmlSerializable { 

    public List<string> Attribs { get; set; } 

    public System.Xml.Schema.XmlSchema GetSchema() { return null; } 

    public void ReadXml(System.Xml.XmlReader reader) { reader.MoveToContent(); } 

    public void WriteXml(System.Xml.XmlWriter writer) { 
     foreach (var entry in this) { 
      writer.WriteStartElement("entry", ""); 
      var label = 1; 
      foreach (var attrib in entry) { 
       writer.WriteAttributeString(string.Format("Attrib{0}", label), attrib); 
       label++; 
      } 
      writer.WriteEndElement(); 
     } 
    } 
} 

... 

var xml = new XmlSerializer(typeof(Example), ""); 
xml.Serialize(stream, example); 
+0

Это выглядит действительно чистым, но дело в том, что количество атрибутов не предопределено, поэтому я не могу использовать этот подход, но это намного более чистое, чем то, что я делаю в настоящее время. Спасибо :) – AnkitSablok

+0

@AnkitSablok Простая настройка, просто добавьте пользовательский класс serialiser – TFD

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