如何在特定条件下通过LINQ和循环创建XML文件?

时间:2018-06-20 17:13:06

标签: c# xml linq

我有一个以下课程的列表项:

public class Itm
   {
       public int Id { get; set; }
       public string PAR1{ get; set; }
       public string PAR2{ get; set; }           
       ...
       public string PAR7{ get; set; }
   }

必须创建具有以下外观的XML文件:

    <?xml version="1.0" encoding="utf-8"?>
<ArrayOfItms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Itm>
    <TYPE>
      <PAR1>value</PAR1>
      <PAR2>value</PAR2>
    </TYPE>
    <NMB>
      <PAR3>value</PAR4>
      <PAR4>value</PAR4>     
    </NMB>
    <ArrOfPR>
      <TPR>
        <PAR5>value</PAR5>
        <PAR6>value</PAR6>
      </TPR>          
    </ArrOfPR>
</Itm>
</ArrayOfItms>

问题在于,如果PAR5和PAR6包含逗号,则有必要将这些值划分在单独的标签<TPR>中。

例如:

itms.PAR5 is equal to 43232,62695
itms.PAR6 is equal to Kursk, Soligorsk

XML文件中的含义必须如此:

<ArrOfPR>
      <TPR>
        <PAR5>43232</PAR5>
        <PAR6>Kursk</PAR6>
      </TPR>    
      <TPR>
        <PAR5>62695</PAR5>
        <PAR6>Soligorsk</PAR6>
      </TPR>        
    </ArrOfPR>

在这种情况下如何使用循环和条件运算符(if..then)?谢谢。

编辑。回答评论:

XDocument xdoc = new XDocument(
            new XElement("ArrayOfItms",
                             new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
                             new XAttribute(XNamespace.Xmlns + "xsd", "http://www.w3.org/2001/XMLSchema")));
    foreach (Itm itm in itms)
    {
        xdoc.Root.Add(new XElement("Itm",
            new XElement("TYPE", new XElement("PAR1", itm.PAR1), new XElement("PAR2", itm.PAR2)),
            new XElement("NMB", new XElement("PAR3", itm.PAR3), new XElement("PAR4", itm.PAR4)),
            new XElement("ArrOfPR",

我无法再插入此类代码(对不起,伪代码):

if (itm.PAR5.Contains(','))
  int indexZap = itm.PAR5.IndexOf(',');
   string firstO = itm.PAR5.Substring(0, indexZap);
   string secondO = itm.PAR5.Substring(indexZap + 2);

   int indexZap2 = itm.PAR6.IndexOf(',');
   string firstG = itm.PAR6.Substring(0, indexZap);
   string secondG = itm.PAR6.Substring(indexZap + 2);

   xdoc.Add(new XElement("TPR"));
   xdoc.Add(new XElement("PAR5", firstG));
   xdoc.Add(new XElement("PAR6", firstO));
   xdoc.Add(new XElement("TPR"));
   xdoc.Add(new XElement("PAR5", secondG));
   xdoc.Add(new XElement("PAR6", secondO));

1 个答案:

答案 0 :(得分:1)

您可以使用Linq Zip函数解决您的问题-它通过索引连接两个序列。这意味着您需要在PAR5中拆分城市列表,然后使用来自PAR6属性的拆分值来压缩列表

对于输入

var itms = new []
{
    new Itm
    {
        PAR1 = "value for Par1",
        PAR2 = "value for Par2",
        PAR3 = "value for Par3",
        PAR4 = "value for Par4",
        PAR5 = "43232,62695",
        PAR6 = "Kursk, Soligorsk",
    },
};

您可以应用此linq查询

var xItems = itms.Select(x => new XElement("Itm",
    new XElement("TYPE",
        new XElement("PAR1", x.PAR1),
        new XElement("PAR2", x.PAR2)
    ),
    new XElement("NMB",
        new XElement("PAR3", x.PAR3),
        new XElement("PAR4", x.PAR4)
    ),
    new XElement("ArrOfPR",
        x.PAR5.Split(',').Zip(x.PAR6.Split(','), (p5, p6) => new
            XElement("TPR",
                new XElement("PAR5", p5),
                new XElement("PAR6", p6)
            ))
    )
  ));

现在您可以组装所有XDocument

var arrayOfItems = new XElement("ArrayOfItms",
    new XAttribute(XNamespace.Xmlns + "xsi", "http://www.w3.org/2001/XMLSchema-instance"),
    new XAttribute(XNamespace.Xmlns + "xsd", "http://www.w3.org/2001/XMLSchema"));
arrayOfItems.Add(xItems);

var xdoc = new XDocument(arrayOfItems);

结果为:

<ArrayOfItms xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Itm>
    <TYPE>
      <PAR1>value for Par1</PAR1>
      <PAR2>value for Par2</PAR2>
    </TYPE>
    <NMB>
      <PAR3>value for Par3</PAR3>
      <PAR4>value for Par4</PAR4>
    </NMB>
    <ArrOfPR>
      <TPR>
        <PAR5>43232</PAR5>
        <PAR6>Kursk</PAR6>
      </TPR>
      <TPR>
        <PAR5>62695</PAR5>
        <PAR6> Soligorsk</PAR6>
      </TPR>
    </ArrOfPR>
  </Itm>
</ArrayOfItms>

注意:为避免Soligorsk多余的空间,您可以将SplitTrim一起使用