C#中CSV转XML格式不符问题排查与修正求助
CSV转XML格式问题排查
我用C#开发CSV转XML功能,已实现基础逻辑,但生成的XML结构不符合预期。以下是我的代码、当前错误输出和目标格式,求排查问题。
现有实现代码
XNamespace xNamespace = "urlhere"; XElement newXML = new XElement(xNamespace + "WarehouseReceipts", new XAttribute("xmlns", "urlhere"), from str in csv let fields = str.Split(',') select new XElement("WarehouseReceipt", new XAttribute("Type", "WH"), new XElement("Number", fields[9]), new XElement("ShipperName", fields[10]), new XElement("ConsigneeName", fields[11]), new XElement("Items", new XElement("Item", new XAttribute("Type", "WI"), new XElement("Satus", fields[0]), new XElement("Pieces", fields[3]), new XElement("Description", fields[2]), new XElement("PackageName", fields[1]), new XElement("Length", new XAttribute("Unit", "in"), fields[4]), new XElement("Volume", new XAttribute("Unit", "ft3"), fields[8]), new XElement("Height", new XAttribute("Unit", "in"), fields[8]), new XElement("Width", new XAttribute("Unit", "in"), fields[6]), new XElement("Weight", new XAttribute("Unit", "lb"), fields[7]), new XElement("WarehouseReceiptNumber", fields[9]) ) ), new XElement("MeasurementUnits", new XElement("LengthUnit", "in"), new XElement("VolumeUnit", "ft3"), new XElement("WeightUnit", "lb") ) ) ); return newXML;
当前错误XML输出
<WarehouseReceipts xmlns="urlhere"> <WarehouseReceipt Type="WH" xmlns=""> <Number>"3519"</Number> <ShipperName>"4 NET NETWORKING CORP"</ShipperName> <ConsigneeName>"ACUAMAR"</ConsigneeName> <Items> <Item Type="WI"> <Satus>"On Hand"</Satus> <Pieces>"10"</Pieces> <Description>"APPLE NEW IPAD"</Description> <PackageName>"Case"</PackageName> <Length Unit="in">"5.00"</Length> <Volume Unit="ft3">"0.60"</Volume> <Height Unit="in">"0.60"</Height> <Width Unit="in">"4.00"</Width> <Weight Unit="lb">"10.00"</Weight> <WarehouseReceiptNumber>"3519"</WarehouseReceiptNumber> </Item> </Items> <MeasurementUnits> <LengthUnit>in</LengthUnit> <VolumeUnit>ft3</VolumeUnit> <WeightUnit>lb</WeightUnit> </MeasurementUnits> </WarehouseReceipt> <WarehouseReceipt Type="WH" xmlns=""> <Number>"3519"</Number> <ShipperName>"4 NET NETWORKING CORP"</ShipperName> <ConsigneeName>"ACUAMAR"</ConsigneeName> <Items> <Item Type="WI"> <Satus>"On Hand"</Satus> <Pieces>"20"</Pieces> <Description>"APPLE IMAC "</Description> <PackageName>"Box"</PackageName> <Length Unit="in">"35.00"</Length> <Volume Unit="ft3">"273.40"</Volume> <Height Unit="in">"273.40"</Height> <Width Unit="in">"15.00"</Width> <Weight Unit="lb">"400.00"</Weight> <WarehouseReceiptNumber>"3519"</WarehouseReceiptNumber> </Item> </Items> <MeasurementUnits> <LengthUnit>in</LengthUnit> <VolumeUnit>ft3</VolumeUnit> <WeightUnit>lb</WeightUnit> </MeasurementUnits> </WarehouseReceipt> </WarehouseReceipts>
期望的目标XML格式
<WarehouseReceipts xmlns="urlhere"> <WarehouseReceipt Type="WH"> <Number>WR-1-22</Number> <ShipperName>shipper</ShipperName> <ConsigneeName>consignee</ConsigneeName> <Items> <Item Type="WI"> <Status>OnHand</Status> <Pieces>3</Pieces> <Description>description2</Description> <PackageName>Package type2</PackageName> <WHRItemID>2</WHRItemID> <Length Unit="in">4.00</Length> <Height Unit="in">4.00</Height> <Width Unit="in">4.00</Width> <Weight Unit="lb">6.00000000000000088818</Weight> <Volume Unit="ft3">0.11000000000000000056</Volume> <Model>model2</Model> <WarehouseReceiptNumber>WR-1-22</WarehouseReceiptNumber> </Item> <Item Type="WI"> <Status>OnHand</Status> <Pieces>4</Pieces> <Description>description</Description> <PackageName>Package type</PackageName> <LocationCode>RCV01</LocationCode> <Length Unit="in">1.00</Length> <Height Unit="in">3.00</Height> <Width Unit="in">2.00</Width> <Weight Unit="lb">16.00</Weight> <Volume Unit="ft3">0.01000000000000000021</Volume> <Model>model</Model> <WarehouseReceiptNumber>WR-1-22</WarehouseReceiptNumber> </Item> </Items> <MeasurementUnits> <LengthUnit>in</LengthUnit> <VolumeUnit>ft3</VolumeUnit> <WeightUnit>lb</WeightUnit> </MeasurementUnits> </WarehouseReceipt> </WarehouseReceipts>
问题分析与修复方案
核心问题点
- 命名空间未统一:子元素
WarehouseReceipt、Number等未使用定义的xNamespace,导致XML自动添加xmlns=""属性,破坏命名空间一致性。 - 数据未分组:当前每一行CSV生成一个独立的
WarehouseReceipt,但目标要求相同Number的行合并到同一个WarehouseReceipt的Items节点下。 - 字段值带引号:CSV分割后的值包含双引号,需要去除。
- 字段索引错误:
Height字段错误使用了fields[8](与Volume重复),需修正为对应索引(比如fields[5],需根据实际CSV结构调整)。 - 拼写错误:
Satus应为Status。 - 缺少目标字段:目标XML包含
WHRItemID、Model、LocationCode等字段,需根据CSV数据补充对应索引。
修复后的代码
XNamespace xNamespace = "urlhere"; // 先处理CSV行,去除引号并分组 var groupedRows = csv .Select(str => str.Split(',').Select(f => f.Trim('"')).ToArray()) .GroupBy(fields => fields[9]); // 按WarehouseReceiptNumber分组 XElement newXML = new XElement(xNamespace + "WarehouseReceipts", new XAttribute(XNamespace.Xmlns + "ns", "urlhere"), // 规范命名空间声明 from group in groupedRows let firstRow = group.First() select new XElement(xNamespace + "WarehouseReceipt", new XAttribute("Type", "WH"), new XElement(xNamespace + "Number", firstRow[9]), new XElement(xNamespace + "ShipperName", firstRow[10]), new XElement(xNamespace + "ConsigneeName", firstRow[11]), new XElement(xNamespace + "Items", from fields in group select new XElement(xNamespace + "Item", new XAttribute("Type", "WI"), new XElement(xNamespace + "Status", fields[0].Replace(" ", "")), // 修正拼写并去除空格 new XElement(xNamespace + "Pieces", fields[3]), new XElement(xNamespace + "Description", fields[2]), new XElement(xNamespace + "PackageName", fields[1]), // 假设WHRItemID和Model对应CSV的其他字段,需根据实际调整索引 new XElement(xNamespace + "WHRItemID", fields[12]), new XElement(xNamespace + "Model", fields[13]), new XElement(xNamespace + "Length", new XAttribute("Unit", "in"), fields[4]), new XElement(xNamespace + "Height", new XAttribute("Unit", "in"), fields[5]), // 修正索引 new XElement(xNamespace + "Width", new XAttribute("Unit", "in"), fields[6]), new XElement(xNamespace + "Weight", new XAttribute("Unit", "lb"), fields[7]), new XElement(xNamespace + "Volume", new XAttribute("Unit", "ft3"), fields[8]), new XElement(xNamespace + "WarehouseReceiptNumber", fields[9]) ) ), new XElement(xNamespace + "MeasurementUnits", new XElement(xNamespace + "LengthUnit", "in"), new XElement(xNamespace + "VolumeUnit", "ft3"), new XElement(xNamespace + "WeightUnit", "lb") ) ) ); return newXML;
说明
- 所有子元素均使用
xNamespace,确保命名空间统一,避免出现xmlns=""。 - 通过
GroupBy将同一仓库收据的行分组,实现多个Item合并到一个WarehouseReceipt下。 - 使用
Trim('"')去除字段值的双引号,Replace(" ", "")将"On Hand"转为"OnHand"。 - 修正了
Height的字段索引,补充了目标XML中的缺失字段(需根据实际CSV结构调整索引)。
内容的提问来源于stack exchange,提问作者Brandon Torrens
相关产品推荐
相关产品推荐

