【发布时间】:2015-05-20 02:45:10
【问题描述】:
我正在从一个循环中制定 xmlnodes。所以它的作用是
var settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;
var ns = new XmlSerializerNamespaces();
ns.Add("", "");
foreach (Person human in bar)
{
var serializer = new XmlSerializer(typeof(Person));
using (var stream = new FileStream(filepath, FileMode.Append))
using (var writer = XmlWriter.Create(stream, settings))
{
serializer.Serialize(writer, human, ns);
}
}
当循环完成时,它会制定 xml 片段,输出 XML 是这样的
<Person>
<Name>mar8a</Name>
<Age>11</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person>
<Person>
<Name>mar1a</Name>
<Age>1</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person>
<Person>
<Name>mar2a</Name>
<Age>11</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person>
<Person>
<Name>mar3a</Name>
<Age>1</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person><Person>
<Name>mar4a</Name>
<Age>11</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person>
<Person>
<Name>mar5a</Name>
<Age>11</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person>
<Person>
<Name>mar6a</Name>
<Age>11</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person>
<Person>
<Name>mar7a</Name>
<Age>11</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person>
<Person>
<Name>mar8a</Name>
<Age>11</Age>
<Sex>MALE</Sex>
<Address>TOP 92 BOTTOM</Address>
<SingleYn>false</SingleYn>
</Person>
我正在运行的问题是如何修改它并使其成为具有根节点并在循环结束时声明的格式良好的 xml。
我尝试了以下概念,但没有运气,因为它限制了我在 writer 上不写任何根元素。
StringBuilder output = new StringBuilder();
XmlReaderSettings ws = new XmlReaderSettings();
ws.ConformanceLevel = ConformanceLevel.Fragment;
String xmlString =
@"<Item>test with a child element stuff</Item>
<Item>test with a child element stuff</Item>";
// Create an XmlReader
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString), ws))
{
XmlWriterSettings ws2 = new XmlWriterSettings();
ws2.Indent = true;
using (XmlWriter writer = XmlWriter.Create(output, ws2))
{
writer.WriteStartDocument();
// Parse the file and display each of the nodes.
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
writer.WriteStartElement(reader.Name);
break;
case XmlNodeType.Text:
writer.WriteString(reader.Value);
break;
case XmlNodeType.XmlDeclaration:
case XmlNodeType.ProcessingInstruction:
writer.WriteProcessingInstruction(reader.Name, reader.Value);
break;
case XmlNodeType.Comment:
writer.WriteComment(reader.Value);
break;
case XmlNodeType.EndElement:
writer.WriteFullEndElement();
break;
}
}
writer.WriteEndDocument();
}
}
更新!!
这是序列化我的序列化器实现的列表的代码
public static async Task WriteXMLAsync<T>(this List<T> listRows, T entity, VMEXPORT[] arrVmExport, string filePath)
where T : class
{
XmlWriterSettings Xmlsettings = new XmlWriterSettings();
Xmlsettings.Indent = true;
Xmlsettings.OmitXmlDeclaration = false;
Xmlsettings.NewLineOnAttributes = true;
Xmlsettings.Async = true;
Xmlsettings.Encoding = Encoding.UTF8;
Xmlsettings.CheckCharacters = false;
XmlAttributeOverrides Xmloverrides = new XmlAttributeOverrides();
XmlAttributes Xmlattribs = new XmlAttributes();
Xmlattribs.XmlIgnore = true;
Xmlattribs.XmlElements.Add(new XmlElementAttribute("SfiObjectState"));
Xmloverrides.Add(typeof(T), "SfiObjectState", Xmlattribs);
if (!File.Exists(filePath))
{
using (var fileStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None, 4096, true))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<T>), Xmloverrides);
using (XmlWriter xmlWriter = XmlWriter.Create(fileStream, Xmlsettings))
{
serializer.Serialize(xmlWriter, listRows);
await xmlWriter.FlushAsync();
}
}
}
else
{
using (var fileStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None, 4096, true))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<T>), Xmloverrides);
using (XmlWriter xmlWriter = XmlWriter.Create(fileStream, Xmlsettings))
{
serializer.Serialize(xmlWriter, listRows);
await xmlWriter.FlushAsync();
}
}
}
}
下面是上面实现 take 和 skip 方法的迭代
public async Task WriteXmlDataAsync<TEntity>(IQueryable<TEntity> listToWrite, [DataSourceRequest]DataSourceRequest dataRequest,
int countno, VMEXPORT[] vmExportarr, CancellationToken token,
TEntity entity, string csvFileNametx, string XmlFilePathtx)
where TEntity : class
{
dataRequest.GroupingToSorting();
int datapageno = (countno / GeneralConst.L_MAX_EXPORT_REC) + 1;
for (int ctrno = 1; ctrno <= datapageno; )
{
if (token.IsCancellationRequested)
{
RemoveTask(csvFileNametx);
token.ThrowIfCancellationRequested();
}
dataRequest.Page = ctrno;
dataRequest.PageSize = GeneralConst.L_MAX_EXPORT_REC;
var dataSourceResult = listToWrite.ToDataSourceResult(dataRequest);
await dataSourceResult.Data.Cast<TEntity>().ToList().WriteXMLAsync(entity, vmExportarr, XmlFilePathtx);
ctrno = ctrno + 1;
int percentageno = (ctrno * 100) / datapageno;
if (percentageno > 100) percentageno = 100;
UpdateTask(csvFileNametx, percentageno);
}
}
【问题讨论】:
-
你不能把整个列表写到 XML 中(可能需要添加包装类来拥有你喜欢的根元素)?
-
我需要批量追加xml片段。 (可扩展性问题)以异步方式制作片段以依次附加数百条记录。如果我在我的场景中编写整个列表,它将有多个根元素
-
如果您不能一次加载人员列表中的所有项目,您可以使用
XmlSerializer以按需加载的块的形式流出整个列表。有关如何执行此操作的示例,请参见此处:stackoverflow.com/questions/28837438/… -
是的,完全正确。您写道,“我需要批量附加 xml 片段”。所以,你有一些方法可以生成你的
Person类的列表,你可以多次调用,对吧?它看起来像什么? -
我将把整个代码。我会更新
标签: c# xml xmlreader xmlwriter