在前一个节点值条件为真时获取XML节点值(不循环)

时间:2015-06-22 16:04:54

标签: xml vb.net linq-to-xml

示例XML -

<?xml version="1.0"?>
<Root>
  <PhoneType dataType="string">
    <Value>CELL</Value>
  </PhoneType>
  <PhonePrimaryYn dataType="string">
    <Value>Y</Value>
  </PhonePrimaryYn>
  <PhoneNumber dataType="string">
    <Value>555-555-5554</Value>
  </PhoneNumber>
  <PhonePrimaryYn dataType="string">
    <Value>Y</Value>
  </PhonePrimaryYn>
  <PhoneType dataType="string">
    <Value>HOME</Value>
  </PhoneType>
  <PhoneNumber dataType="string">
    <Value>555-555-5555</Value>
  </PhoneNumber>    
</Root>

如果没有循环遍历每个节点列表,有人可以告诉我(使用LINQ-to-XML或其他方式)我如何执行以下操作?

在XML示例中,您会看到两组“PhoneType”,“PhonePrimaryYn”和“PhoneNumber”类型代码组。第一组三个相互关联。第二组三者也相互关联,依此类推。

让我们说我想知道手机号码是什么。

当'PhoneType''Value'为'CELL','PhonePrimaryYn''Value'为'Y'时,我得到那个手机号码,我得到'PhoneNumber''Value'为'555-555-5554 ”。你希望得到这个想法。

我想知道是否有可能获得'PhoneNumber'值(例如手机)而无需遍历特定类型的每个节点列表组。

有人有任何想法吗?

2 个答案:

答案 0 :(得分:0)

就个人而言,我会改变XML的工作方式,以便您在一个块中获得一个电话号码的所有信息,如下所示

<phoneStructure>
   <type>CELL</type>
   <value>0123</value>
   <primary>false</primary>
</phoneStructure>

然后,您可以使用此XPath选择手机所在的整个手机结构,或将其更改为主手机,然后从那里读取值。

//PhoneStructure[Type='Cell']

如果您需要更多帮助,请告诉我。

答案 1 :(得分:0)

更新

使用XDocument与XmlDocument,我相信这样做可以在不使用循环的情况下提出要求。

这取决于

顺序的元素

<PhoneType> <PhonePrimaryYN> <PhoneNumber>

string xml = "<?xml version=\"1.0\"?>" +
    "<Root>" + 
    "  <PhoneType dataType=\"string\">" + 
    "    <Value>CELL</Value>" + 
    "  </PhoneType>" + 
    "  <PhonePrimaryYn dataType=\"string\">" + 
    "    <Value>Y</Value>" + 
    "  </PhonePrimaryYn>" + 
    "  <PhoneNumber dataType=\"string\">" + 
    "    <Value>555-555-5554</Value>" + 
    "  </PhoneNumber>" + 
    "  <PhonePrimaryYn dataType=\"string\">" + 
    "    <Value>Y</Value>" + 
    "  </PhonePrimaryYn>" + 
    "  <PhoneType dataType=\"string\">" + 
    "    <Value>HOME</Value>" + 
    "  </PhoneType>" + 
    "  <PhoneNumber dataType=\"string\">" + 
    "    <Value>555-555-5555</Value>" + 
    "  </PhoneNumber>    " +
    "  <PhoneType dataType=\"string\">" +
    "    <Value>CELL</Value>" +
    "  </PhoneType>" +
    "  <PhonePrimaryYn dataType=\"string\">" +
    "    <Value>Y</Value>" +
    "  </PhonePrimaryYn>" +
    "  <PhoneNumber dataType=\"string\">" +
    "    <Value>555-555-9999</Value>" +
    "  </PhoneNumber>" + 
    "</Root>";

XDocument xDoc = XDocument.Parse(xml);
if (xDoc.Root != null)
{
    var tmp = (from item in xDoc.Root.Descendants()
                where item.Name == "PhoneType" && item.Value == "CELL"
                select new
                            {
                                PhoneNumber = item.NextNode.NextNode
                            }).ToList();

    for (int i = 0; i < tmp.Count; i++)
    {
        Console.WriteLine(((XElement)tmp[i].PhoneNumber).Value);
    }
}

结果:

555-555-5554
555-555-9999

OLD ANSWER

当我将示例XML加载到XmlDocument时,我看到它的InnerText属性包含以下内容:

CELLY555-555-5554YHOME555-555-5555

从这里开始,我认为Regex是一种使用模式提取CELL数字的好方法:

"CELL[NY](\\d{3}-\\d{3}-\\d{4})"

该模式寻找单词&#34; CELL&#34;,然后是&#39; N&#39;或者&#39; Y&#39;,然后是###-###-#####格式的电话号码。电话号码在捕获组中,如果找到匹配,则可以像下面的示例所示访问它。

我添加了另一个CELL条目,表明您可以获取XML中的所有CELL编号。因此,InnerText的{​​{1}}属性现在看起来像

XmlDocument

CELLY555-555-5554YHOME555-555-5555CELLY555-555-9999

结果:

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml("<?xml version=\"1.0\"?>" +
    "<Root>" + 
    "  <PhoneType dataType=\"string\">" + 
    "    <Value>CELL</Value>" + 
    "  </PhoneType>" + 
    "  <PhonePrimaryYn dataType=\"string\">" + 
    "    <Value>Y</Value>" + 
    "  </PhonePrimaryYn>" + 
    "  <PhoneNumber dataType=\"string\">" + 
    "    <Value>555-555-5554</Value>" + 
    "  </PhoneNumber>" + 
    "  <PhonePrimaryYn dataType=\"string\">" + 
    "    <Value>Y</Value>" + 
    "  </PhonePrimaryYn>" + 
    "  <PhoneType dataType=\"string\">" + 
    "    <Value>HOME</Value>" + 
    "  </PhoneType>" + 
    "  <PhoneNumber dataType=\"string\">" + 
    "    <Value>555-555-5555</Value>" + 
    "  </PhoneNumber>    " +
    "  <PhoneType dataType=\"string\">" +
    "    <Value>CELL</Value>" +
    "  </PhoneType>" +
    "  <PhonePrimaryYn dataType=\"string\">" +
    "    <Value>Y</Value>" +
    "  </PhonePrimaryYn>" +
    "  <PhoneNumber dataType=\"string\">" +
    "    <Value>555-555-9999</Value>" +
    "  </PhoneNumber>" + 
    "</Root>");

Match match = Regex.Match(xmlDocument.InnerText, "CELL[NY](\\d{3}-\\d{3}-\\d{4})");
while (match.Success)
{
    Console.WriteLine(match.Groups[1]);
    match = match.NextMatch();
}