当数据集WriteXml()函数生成xml文件时,C#如何使用XDocument类更新xml文件
Posted
技术标签:
【中文标题】当数据集WriteXml()函数生成xml文件时,C#如何使用XDocument类更新xml文件【英文标题】:C# How to update xml file using XDocument class when xml file generated by dataset WriteXml() function 【发布时间】:2021-09-19 14:46:24 【问题描述】:我正在寻找一些指导方针,如何使用XDocument
更新我的复杂 XML。 XML 看起来很复杂,因为它是从DataSet.WriteXml()
生成的
这是我的 XML 首先是由QCSavedData.WriteXml(@strQCViewAllPath);
QCSavedData 生成的数据集:
<?xml version="1.0" standalone="yes"?>
<HNNMY_ViewAll>
<dgvViewAll_Vertical>
<Section_x0020_>MS</Section_x0020_>
<LineItem>Morgan Stanley</LineItem>
<Revise_x0020_Date>10-09-2020</Revise_x0020_Date>
<_x0032_010_x0020_FYA>126,966.0000</_x0032_010_x0020_FYA>
<_x0032_011_x0020_FYA>128,810.0000</_x0032_011_x0020_FYA>
<_x0032_012_x0020_FYA>140,948.0000</_x0032_012_x0020_FYA>
<_x0032_013_x0020_FYA>150,090.0000</_x0032_013_x0020_FYA>
<_x0031_Q_x0020_2014A>37,524.0000</_x0031_Q_x0020_2014A>
<_x0032_Q_x0020_2014A>44,181.0000</_x0032_Q_x0020_2014A>
<_x0033_Q_x0020_2014A>45,259.0000</_x0033_Q_x0020_2014A>
<_x0034_Q_x0020_2014A>49,656.0000</_x0034_Q_x0020_2014A>
<_x0032_014_x0020_FYA>176,620.0000</_x0032_014_x0020_FYA>
<_x0031_Q_x0020_2015A>46,791.0000</_x0031_Q_x0020_2015A>
<_x0032_Q_x0020_2015A>53,233.0000</_x0032_Q_x0020_2015A>
<_x0033_Q_x0020_2015A>53,420.0000</_x0033_Q_x0020_2015A>
<_x0034_Q_x0020_2015A>56,477.0000</_x0034_Q_x0020_2015A>
<_x0032_015_x0020_FYA>209,921.0000</_x0032_015_x0020_FYA>
<_x0031_Q_x0020_2016A>50,624.0000</_x0031_Q_x0020_2016A>
<_x0032_Q_x0020_2016A>54,341.0000</_x0032_Q_x0020_2016A>
<_x0033_Q_x0020_2016A>56,802.0000</_x0033_Q_x0020_2016A>
<GroupKey>Consensus Model~Total Revenue Including VAT~RD_001~NBM~~1~MS</GroupKey>
</dgvViewAll_Vertical>
</HNNMY_ViewAll>
看到这是<Section_x0020_>MS</Section_x0020_>
如何查询当section是MS,因为Section有x0020?
看到这个
<_x0032_010_x0020_FYA>126,966.0000</_x0032_010_x0020_FYA>
数据表有很多列,如 2010 FYA、2011 FYA .... 1Q 2014A 但是当数据表数据保存在 xml 中时,它会以这种方式显示 <_x0032_010_x0020_FYA>126,966.0000</_x0032_010_x0020_FYA>
那么我该如何更新这个标签内的值?
看到这个<GroupKey>Consensus Model~Total Revenue Including VAT~RD_001~NBM~~1~MS</GroupKey>
我必须这样查询
XDocument
表示当 Section == GroupKey.Split('~')[5] AND Column Name is 2010 FYA 然后更新 内部的值>column 2010 FYA 表示该列的值 <_x0032_010_x0020_FYA>126,966.0000</_x0032_010_x0020_FYA>
请帮助我提供指导我如何更新 XML 的示例代码。
【问题讨论】:
它复杂的唯一原因是您的数据集列名有空格并且以数字开头。 xml 标签不允许第一个字符是数字,也不允许标签名称中包含空格。 先生,您能否分享一些想法如何使用 xdocument 类更新我的 xml 数据。 您需要修复列名或使用“AS”将名称映射到其他内容。您使用什么查询来获取数据? 【参考方案1】:将DataSet
写入XML 时,输出将显示在DataTable.WriteXml()
的文档中。它看起来像:
<DataSetName>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!--Schema information here, if you have requested it -->
</xs:schema>
<!--The first table: -->
<Table1Name> <!--This repeats for every row in Table1 -->
<!-- Column values -->
<Column1Name>Value 1.1</Column1Name>
<Column2Name>Value 2.1</Column2Name>
</Table1Name>
<Table1Name>
<!-- Column values -->
<Column1Name>Value 1.2</Column1Name>
<Column2Name>Value 2.2</Column2Name>
</Table1Name>
<!--The second table: -->
<Table2Name> <!--This repeats for every row in Table2 -->
<!-- Column values -->
<ColumnName>Value</ColumnName>
</Table2Name>
<!--And the remaining tables if any follow sequentially -->
</DataSetName>
请注意,数据集、表和列名变成了 XML 元素名。但是,并非每个字符串都可以用作格式良好的 XML 元素名称,该名称由 XML standard 定义。稍微简化一下,格式良好的元素名称必须:
以 Unicode 字母或_
开头。
随后由 Unicode 字母数字字符组成,_
、-
或 .
。
因此2010 FYA
不能是格式正确的 XML 元素名称,因为它以数字字符开头并包含空格。因此,在这种情况下,框架使用XmlConvert.EncodeLocalName(String)
将任意字符串编码为格式良好的 XML 名称:
此方法与
EncodeName
方法类似,不同之处在于它对冒号字符进行编码,从而保证名称可以用作命名空间限定名称的本地名称部分。
以及相关的XmlConvert.EncodeName(String)
:
此方法转换无效字符,例如空格或半角片假名,需要在不支持或不存在模式的情况下映射到 XML 名称。无效字符被转换为转义的数字实体编码。
转义字符是“_”。任何不符合XML 1.0 spec (fourth edition) 建议的 XML 名称字符都将转义为 xHHHH。 HHHH 字符串代表最高有效位第一顺序中字符的四位十六进制 UCS-2 代码。例如,名称 Order Details 编码为 Order_x0020_Details。
下划线字符不需要转义,除非它后面跟着一个字符序列,在解码名称时,该字符序列与下划线一起可能被误解为转义序列。例如,Order_Details 未编码,但 Order_x0020_ 编码为 Order_x005f_x0020_。不允许使用简写形式。例如,x20 和 __ 的形式不会生成。
如果您想使用数据集、表或列名称查询 XML,您必须调用 XmlConvert.EncodeLocalName(name)
来确定 XML 中使用的名称。反之,如果要查询从 XML 中读取的某个元素名称的数据集,则必须调用 XmlConvert.DecodeName(String)
重新生成原始名称。
例如要更新某些XDocument xdocument
中的2010 FYA
列,您可以这样做:
var tableName = XmlConvert.EncodeLocalName("dgvViewAll_Vertical"); // EncodeLocalName is not strictly needed here since dgvViewAll_Vertical happens to be a well-formed XML name
var sectionName = XmlConvert.EncodeLocalName("Section ");
var groupKeyName = XmlConvert.EncodeLocalName("GroupKey"); // EncodeLocalName is not strictly needed here since GroupKey happens to be a well-formed XML name
var columnName = XmlConvert.EncodeLocalName("2010 FYA");
var columnValue = "New Value";
var ns = xdocument.Root.Name.Namespace;
var columns = xdocument.Root
.Elements(ns + tableName)
// Add error handling here when groupKeyName is not found or not in the expected syntax
.Where(e => e.Element(ns + sectionName)?.Value == e.Element(ns + groupKeyName).Value.Split('~').Last())
.Select(e => e.Element(ns + columnName));
foreach (var column in columns)
column.Value = columnValue;
请注意,此代码假定您的 data set、data tables 和 data columns 都使用相同的 XML 命名空间(上面代码中的 ns
)。对于您的问题中显示的 XML,这是正确的。如果不是这样,则在查询表名和列名时需要使用适当的命名空间。
演示小提琴here.
【讨论】:
以上是关于当数据集WriteXml()函数生成xml文件时,C#如何使用XDocument类更新xml文件的主要内容,如果未能解决你的问题,请参考以下文章
.net怎样把sql2005数据库表中的内容生成xml文件?