【问题标题】:How to get all child element names and values inside a particular element in an XML tag如何获取 XML 标记中特定元素内的所有子元素名称和值
【发布时间】:2023-03-10 13:34:01
【问题描述】:

我有一个带有多个标签的 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|等……”

是否有任何可以使用的 Regex 或 Xpath...??或任何其他解决方法

【问题讨论】:

  • 在您的实际输入中,cmets 和间距是否完全相同? &lt;!-- End U_C_B-&gt; 不是有效评论。 &lt;/ ATXYCB&gt; 不是有效标签。

标签: c# .net regex xml xpath


【解决方案1】:

如果你有这样的输入(空间问题和无效的 cmets),我建议两种方法:基于 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);
}

这两种方法都会导致:

【讨论】:

  • 如果它对您有用,请考虑接受答案(在向下箭头下方左侧打勾)。
【解决方案2】:

您可以将 XML 解析与 XDocument 一起使用:

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

【讨论】:

  • 如果文件包含与示例输入中相同的错误,则需要在使用XDocument 解析之前进行预处理。
猜你喜欢
  • 1970-01-01
  • 2011-05-06
  • 2021-05-24
  • 1970-01-01
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
  • 2015-10-03
  • 2016-07-15
相关资源
最近更新 更多