0

我想使用 C# 中的 XmlWriter 类生成以下格式的 XML -:

<?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="" />
4

3 回答 3

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

于 2015-12-11T18:56:18.730 回答
0

试试 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();


        }
    }
}
​
于 2015-12-11T18:10:48.010 回答
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);
于 2015-12-11T20:20:30.247 回答