使用单个字符串

时间:2017-03-31 19:47:50

标签: c# linq-to-xml data-manipulation

拥有这样的XML:

<ReplyMessage>
  <tran>
    <ser_num>305</ser_num>
    <time>1490987995</time>
    <source_type>0</source_type>
    <source_number>0</source_number>
    <tran_type>126</tran_type>
    <tran_code>50</tran_code>
    <t_diag>
      <bfr>S</bfr>
      <bfr>o</bfr>
      <bfr>c</bfr>
      <bfr>k</bfr>
      <bfr>e</bfr>
      <bfr>t</bfr>
      <bfr></bfr>
      <bfr>r</bfr>
      <bfr>e</bfr>
      <bfr>c</bfr>
      <bfr>v</bfr>
      <bfr></bfr>
      <bfr>o</bfr>
      <bfr>n</bfr>
      <bfr></bfr>
      <bfr>s</bfr>
      <bfr>o</bfr>
      <bfr>c</bfr>
      <bfr>k</bfr>
      <bfr>e</bfr>
      <bfr>t</bfr>
      <bfr>-</bfr>
      <bfr>7</bfr>
      <bfr>4</bfr>
      <bfr>:</bfr>
      <bfr></bfr>
      <bfr>f</bfr>
      <bfr>a</bfr>
      <bfr>i</bfr>
      <bfr>l</bfr>
      <bfr>e</bfr>
      <bfr>d</bfr>
      <bfr></bfr>
      <bfr>-</bfr>
      <bfr></bfr>
      <bfr>3</bfr>
      <bfr>0</bfr>
      <bfr>7</bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
      <bfr></bfr>
    </t_diag>
  </tran>
</ReplyMessage>

我希望使用简单的字符串元素替换<bfr>下的嵌套<t_diag>元素数组:

<ReplyMessage>
  <tran>
    <ser_num>305</ser_num>
    <time>1490987995</time>
    <source_type>0</source_type>
    <source_number>0</source_number>
    <tran_type>126</tran_type>
    <tran_code>50</tran_code>
    <t_diag>
      <bfr>Socket recv on socket-74: failed - 307</bfr>
    </t_diag>
  </tran>
</ReplyMessage>

因此,从StackOverflow和MSDN拼凑了几个帖子,我得到了这个方法,它完成了这项工作:

private XElement XmlPivotCharArrayToStr(XDocument xmlDoc, string parentName, string arrayName)
{
    XElement parent = xmlDoc.Descendants().Where(n => n.Name == parentName).FirstOrDefault();
    string st = string.Join("", parent.Elements(arrayName).Select(x => string.IsNullOrEmpty(x.Value) ? " " : x.Value)).TrimEnd();
    parent.RemoveAll();
    XElement newElement = new XElement(arrayName, st);
    parent.Add(newElement);
    return newElement;
}

这样称呼:

    //// Some initial cleanup to convert character array into string
    XmlPivotCharArrayToStr(xmlDoc, parentName: "t_diag", arrayName: "bfr");

现在,这在我的具体情况下有效,但我觉得可以做出一些改进:

  1. 有没有办法可以指定一个显式的parentName路径,而不是使用.Descendants()方法?
  2. 有没有更好的方法来换出数组并用字符串替换它? - parent.RemoveAll()可能有点矫枉过正。
  3. 有没有办法检测数组的结尾以避免使用TrimEnd()
  4. 提前感谢任何提示 - 我希望其他人找到(改进后的版本)这个有用。

1 个答案:

答案 0 :(得分:1)

  1. 您可以使用xpath选择目标节点。为此,使用扩展方法(添加using System.Xml.XPath)。然后就是:

    XElement parent = xmlDoc.XPathSelectElement(path);
    
  2. 您案件中的path"/ReplyMessage/tran/t_diag"

    1. 我认为RemoveAll很好,但如果您有疑问,可以删除t_diag本身,如下所示:

      XElement newElement = new XElement(arrayName, st);
      var grandParent = parent.Parent;
      parent.Remove();
      grandParent.Add(new XElement(parent.Name, newElement));
      
    2. TrimEnd没问题。要检测最后的所有元素是否都是空的,你无论如何都需要观察它们 - 所以你不能做得更好。