如何获取XML标记中特定元素内的所有子元素名称和值

时间:2015-08-21 06:14:45

标签: c# .net regex xml xpath

我有一个XML形式的字符串,其中包含许多标记:

<Code>
<!-- Schema Version MQ Message blocks -->
    <T_C_B>
        < ATXYCB>ABC11</ ATXYCB>
        <BTCWZB>EFG22</BTCWZB>
        < CTATCB>IJK33</CTATCB>
        < DTCAAB>LMN44</DTCAAB>
        <!-- End T_C_B -->
    </T_C_B>

    <D_C_B>
        < ADCB>xs:string</ ADCB>
        < BDCB>xs:string</ BDCB>
        < CDCB>xs:string</ CDCB>
    <!-- End D_ C_B-->
    </D_C_B>
    <U_C_B>
        <UATXYCB>AA2B</ UATXYCB>
        <BUTCWZB>BB4C</BUTCWZB>
        < UCTATCB>C8CD</UCTATCB>
        < DTUCAAB>D9DE</DTUCAAB>
    <!-- End U_C_B->
    </U_C_B>
</Code>

我需要找到T_C_B和U_C_B中的元素及其值,并与“|”之类的分隔符连接:

  

ATXYCB = ABC11 | BTCWZB = EFG22 | CTATCB = IJK33 | DTCAAB = LMN44 | UATXYCB = AA2B |等......”

是否有可以使用的正则表达式或Xpath ......或任何其他解决方法

2 个答案:

答案 0 :(得分:0)

您可以对XDocument使用XML解析:

string str = "";
XDocument doc = XDocument.Load(filename);
IEnumerable<XElement> elements = doc.Root.Elements();
foreach (XElement e in elements)
{
    if ((e.Name == "T_C_B") || (e.Name == "U_C_B"))
    {
         IEnumerable<XElement> nextElmt = e.Elements();
         foreach (XElement x in nextElmt)
         {
              str += string.Format("{0}={1}", x.Name, x.Value);
              str += "|";
         }
    }
}

str = str.Remove(str.Length - 1, 1);
Console.WriteLine(str);

您可以在此处试用:https://dotnetfiddle.net/kOudWl

答案 1 :(得分:0)

如果你有这样的输入(有空格问题和无效的评论),我建议两种方式:基于XML和基于正则表达式(作为后备)。

XML方式

它包括修复阻止使用XElement进行解析然后进行实际解析的问题:

var xml = "<<YOUR_XML>>";
xml = Regex.Replace(xml, @"<\s+([\w:-])", "<$1");
xml = Regex.Replace(xml, @"</\s+([\w:-]+>)", "</$1");
xml = Regex.Replace(xml, @"(?s)<!--.*?->", string.Empty);
XElement xe = null;
try
{
   xe = XElement.Parse(xml);
   var tags = xe.DescendantsAndSelf()
      .Where(p => p.Name == "T_C_B" || p.Name == "U_C_B")
      .Select(p => new { names = p.Descendants()
                      .Select(m => m.Name.LocalName + "=" + m.Value)
                      .ToList() })
      .ToList();
   var res = string.Empty;
   foreach (var s in tags)
      res += (string.IsNullOrEmpty(res) ? "" : "|") +
               string.Join("|", s.names);
}
catch(Exception e) 
{

}

正则表达方式

您可以使用以下正则表达式来处理您的数据:

<\s*[UT]_C_B\s*>(?:\s*<\s*(?<name>[^<]*)>(?<val>[^<]*)<\s*/\s*\k<name>>.*?)+

请参阅demo

C#代码:

var rx = new Regex(@"<\s*[UT]_C_B\s*>(?:\s*<\s*(?<name>[^<]*)>(?<val>[^<]*)<\s*/\s*\k<name>>.*?)+", RegexOptions.Singleline);
var matchColl = rx.Matches(xml);
var result = string.Empty;
foreach (Match m in matchColl)
{ 
    for(int y = 0; y < m.Groups["name"].Captures.Count; y++)
        result += (string.IsNullOrEmpty(result) ? "" : "|") + 
             string.Format("{0}={1}", m.Groups["name"].Captures[y].Value, 
                                  m.Groups["val"].Captures[y].Value);
}

这两种方法都会产生:

enter image description here