我尝试在xml文件中保存我的应用程序中的一些元素,但是当我开始使用此代码开发它时:
public static void WriteInFile(string savefilepath)
{
XmlWriter writer = XmlWriter.Create(savefilepath);
WriteXMLFile(writer);
}
private static void WriteXMLFile(XmlWriter writer) //Write and Create XML profile for specific type
{
writer.WriteStartDocument();
writer.WriteStartElement("cmap");
writer.WriteAttributeString("xmlns", "dcterms",null, "http://purl.org/dc/terms/");
writer.WriteElementString("xmlns", "http://cmap.ihmc.us/xml/cmap/");
// writer.WriteAttributeString("xmlns","dc",null, "http://purl.org/dc/elements/1.1/");
//writer.WriteAttributeString("xmlns", "vcard", null, "http://www.w3.org/2001/vcard-rdf/3.0#");
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Close();
}
Run Code Online (Sandbox Code Playgroud)
我发现记事本中的输出是这样的一行:
<?xml version="1.0" encoding="utf-8"?><cmap
xmlns:dcterms="http://purl.org/dc/terms/"><xmlns>http://cmap.ihmc.us/xml/cmap/</xmlns></cmap>
Run Code Online (Sandbox Code Playgroud)
我想它看起来像这样的多线:
<?xml version="1.0" encoding="utf-8"?> <cmap
xmlns:dcterms="http://purl.org/dc/terms/"><xmlns>http://cmap.ihmc.us/xml/cmap/</xmlns>
</cmap>
Run Code Online (Sandbox Code Playgroud) 我正在用C#编写Windows服务.我有一个XmlWriter包含XSLT转换输出的内容.我需要将XML放入一个XMLElement对象中以传递给Web服务.
做这个的最好方式是什么?
我正在使用Entity Framework查询父/子结果集的数据,我想将此数据导出到XML文档.
var agreement = storeops.Agreements.SingleOrDefault(a => a.AgreementNumber == AgreementTextBox.Text);
XmlSerializer serializer = new XmlSerializer(agreement.GetType());
XmlWriter writer = XmlWriter.Create("Agreement.xml");
serializer.Serialize(writer, agreement);
Run Code Online (Sandbox Code Playgroud)
这很有效,除了它只序列化父级而不在XML中包含相关的子记录.我怎样才能让孩子们序列化呢?
我也尝试使用POCO生成的代码,并且子集合尝试序列化,除非它们是无法序列化的ICollections.
无法序列化System.Collections.Generic.ICollection`1 [[DataSnapshots.AgreementItem,DataSnapshots,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]类型的成员DataSnapshots.Agreement.AgreementItems,因为它是一个接口.
entity entity-framework xmlwriter xml-serialization eager-loading
鉴于此代码(C#,.NET 3.5 SP1):
var doc = new XmlDocument();
doc.LoadXml("<?xml version=\"1.0\"?><root>"
+ "<value xml:space=\"preserve\">"
+ "<item>content</item>"
+ "<item>content</item>"
+ "</value></root>");
var text = new StringWriter();
var settings = new XmlWriterSettings() { Indent = true, CloseOutput = true };
using (var writer = XmlWriter.Create(text, settings))
{
doc.DocumentElement.WriteTo(writer);
}
var xml = text.GetStringBuilder().ToString();
Assert.AreEqual("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n<root>\r\n"
+ " <value xml:space=\"preserve\"><item>content</item>"
+ "<item>content</item></value>\r\n</root>", xml);
Run Code Online (Sandbox Code Playgroud)
断言失败是因为在元素XmlWriter周围插入换行符和缩进<item>,这似乎与xml:space="preserve"属性相矛盾。
我试图接受没有空格的输入(或只有重要的空格,并且已经加载到XmlDocument)并漂亮地打印它而不在标记为保留空格的元素内添加任何空格(出于显而易见的原因)。
这是一个错误还是我做错了什么?有没有更好的方法来实现我想要做的事情?
编辑:我可能应该补充一点,我必须在输出端使用XmlWriterwith Indent=true。在“真实”代码中,这是从我的代码外部传入的。
我正在尝试使用C#中的System.Xml.Xmlwriter创建具有多个名称空间的XML文档,并在编译时收到以下错误:
在同一个开始元素标记内,前缀''无法从''重新定义为'http://www.acme.com/BOF'.
我的全部代码如下:
XmlWriterSettings settings = new XmlWriterSettings { Encoding = Encoding.UTF8, Indent = true };
XmlWriter writer = XmlWriter.Create("C:\\ACME\\xml.xml", settings);
writer.WriteStartDocument();
writer.WriteStartElement("BOF");
writer.WriteAttributeString("xmlns", null, null, "http://www.acme.com/BOF"); //This is where I get my error
writer.WriteAttributeString("xmlns", "xsi", null, "http://www.w3.org/2001/XMLSchema-instance");
writer.WriteAttributeString("fileName", null, null, "test.xml");
writer.WriteAttributeString("date", null, null, "2011-10-25");
writer.WriteAttributeString("origin", null, null, "MYORIGIN");
writer.WriteAttributeString("ref", null, null, "XX_88888");
writer.WriteEndElement();
writer.WriteStartElement("CustomerNo");
writer.WriteString("12345");
writer.WriteEndElement();
writer.WriteEndDocument();
writer.Flush();
writer.Close();
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
谢谢
约翰
有什么方法可以组合两个 XmlDocuments 而不将第一个保存在内存中?
我必须循环浏览多达一百个大(~300MB)XML 文件的列表,附加到每个多达 1000 个节点,重复整个过程几次(因为新节点列表被清除以节省内存)。目前我XmlDocument在追加新节点之前将整个加载到内存中,这目前是站不住脚的。
你认为最好的方法是什么?我有一些想法,但我不确定哪个是最好的:
XMLDocument,而是使用XmlReader和XmlWriter同时写入临时文件,该文件随后被重命名。XmlDocument仅用于新节点,然后手动将其写入现有的文件(即file.WriteLine( "<node>\n" )任何帮助都感激不尽。
编辑一些更多细节以回答一些评论:
该程序将几个大型日志解析为 XML,按来源分组到不同的文件中。它只需要每天运行一次,并且一旦编写了 XML,就会有一个轻量级的专有阅读器程序来提供有关数据的报告。该程序每天只需要运行一次,所以可能会很慢,但运行在执行其他操作的服务器上,主要是文件压缩和传输,不能影响太多。
数据库可能会更容易,但公司不会很快这样做!
按原样,程序在开发机器上运行最多只使用几 GB 的内存,但在服务器上运行时会抛出内存不足的异常。
最终编辑 该任务的优先级很低,这就是为什么获取数据库只需要额外花费的原因(尽管我会研究 mongo)。
该文件只会被附加到,并且不会无限增长 - 每个最终文件仅用于一天的日志,然后在第二天生成新文件。
我可能会使用 XmlReader/Writer 方法,因为它最容易确保 XML 有效性,但我已经考虑了您的所有评论/答案。我知道拥有这么大的 XML 文件并不是一个特别好的解决方案,但这是我的限制,所以感谢提供的所有帮助。
我有一个非常大的XML文件(数百万条记录).由于速度和内存限制,我打算使用XMLReader/ XMLWriter.
我需要读取文件,获取一条记录,更改其属性,最后再次保存XML.
为了测试,我创建了一个XML文件,并使用以下行将一些记录写入其中:
$doc = new XMLWriter();
$doc->openURI($xmlFile);
$doc->startDocument('1.0','UTF-8');
$doc->setIndent(4);
$doc->startElement('DBOS');
for($r=0;$r<10; $r++){
$doc->startElement('ITEMS');
for($i=0;$i<5; $i++){
$doc->startElement('ITEM');
$doc->writeAttribute('id', $r.'-'.$i);
$doc->endElement();
}
$doc->endElement();
}
$doc->endElement();
$doc->endDocument();
$doc->flush();
Run Code Online (Sandbox Code Playgroud)
我用这个再读一遍:
$reader = new XMLReader();
if (!$reader->open($xmlFile)){
die("Failed to open 'data.xml'");
}
while($reader->read()){
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'ITEMS') {
$node = $reader->expand();
$items = $node->childNodes;
foreach ($items as $ik => $itm ){
print $itm->textContent.'<br/>';
// how to change the ID Attribute of a Node (DomNode) and save …Run Code Online (Sandbox Code Playgroud) 我上次使用已经有一段时间了,XmlWriter但因为今天是编写一些 XML 的幸运日,所以我开始...Async默认使用所有方法,但立即出现以下异常:
System.InvalidOperationException :如果要使用异步方法,请将 XmlWriterSettings.Async 设置为 true。
我必须在传递给构造函数的设置对象上设置一个标志,这对我来说似乎有点奇怪,XmlWriter以便我可以在类上打开方法的使用。
例如:
using (var xmlWriter = XmlWriter.Create(stringBuilder))
{
await xmlWriter.WriteStartElementAsync("", "root", "")
.ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
但是会抛出异常:
using (var xmlWriter = XmlWriter.Create(stringBuilder, new XmlWriterSettings(){Async = true}))
{
await xmlWriter.WriteStartElementAsync("", "root", "")
.ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
会工作得很好。
有谁知道这背后的原因?
有没有办法在 XmlWriter 中使用 WriteStartElement 函数,如下所示:
XmlWriter.WriteStartElement("prefix", "name", null);
Run Code Online (Sandbox Code Playgroud)
发生错误:System.ArgumentException:“无法使用带有空命名空间的前缀。”
我不想在创建元素时设置命名空间 URI。
稍后,当创建其他属性时,我将通过 WriteAttributeString() 添加它。
如果数据在一行上
index=int.Parse(logDataReader.ReadElementContentAsString());
,则
value=double.Parse(logDataReader.ReadElementContentAsString(),
使光标向前移动。如果我取消这些调用,我会看到它在调试中循环了 6 次。
在下面<data>的第一个 ( <logData id="Bravo">) 中只读取了3 个(并且它们是错误的,因为该值用于下一个索引)。在第二个 ( <logData id="Bravo">) 上,所有内容<data>都已读取。
由于该文件是动态创建的(由 XMLwriter),因此无法编辑 xml 并插入换行符。该NewLineChars设置是换行。从 XMLwriter 开始,它实际上只是一行 - 我将它分解以找出它在哪里中断。在浏览器中它正确显示。
如何解决这个问题?
这是我的 XML:
<?xml version="1.0" encoding="utf-8"?>
<log>
<logData id="Alpha">
<data><index>100</index><value>150</value></data>
<data><index>110</index><value>750</value></data>
<data><index>120</index><value>750</value></data>
<data><index>130</index><value>150</value></data>
<data><index>140</index><value>0</value></data>
<data><index>150</index><value>222</value></data>
</logData>
<logData id="Bravo">
<data>
<index>100</index>
<value>25</value>
</data>
<data>
<index>110</index>
<value>11</value>
</data>
<data>
<index>120</index>
<value>1</value>
</data>
<data>
<index>130</index>
<value>25</value></data>
<data>
<index>140</index>
<value>0</value>
</data>
<data>
<index>150</index>
<value>1</value>
</data>
</logData>
</log>
Run Code Online (Sandbox Code Playgroud)
还有我的代码:
static void Main(string[] …Run Code Online (Sandbox Code Playgroud)