当前面的节点值条件为真时获取 XML 节点值(不循环)
Get XML node value when previous node value conditions are true (without looping)
样本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' 类型代码组。第一组三个相互关联。第二组三个也相互关联,依此类推。
假设我想知道单元格 phone 的号码是多少。
当 'PhoneType' 'Value' 为 'CELL','PhonePrimaryYn' 'Value' 为 [=34= 时,我得到那个单元格 phone 编号], 我得到 '555-555-5554' 的 'PhoneNumber' 'Value'。希望你明白了。
我想知道是否有可能获得 'PhoneNumber' 值(例如单元格 phone)而不必遍历特定类型的每个节点列表组。
有人有什么想法吗?
就我个人而言,我会更改 XML 的工作方式,这样您就可以像这样在一个块中获得一个 phone 号码的所有信息
<phoneStructure>
<type>CELL</type>
<value>0123</value>
<primary>false</primary>
</phoneStructure>
然后您可以使用此 XPath select 整个 phone 结构,其中它是一个单元格 phone 或将其更改为主要的,然后从那里读取值。
//PhoneStructure[Type='Cell']
如果您需要更多帮助,请告诉我。
更新
使用 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
旧答案
当我将您的示例 XML 加载到 XmlDocument
中时,我看到它 InnerText
属性 包含以下内容:
CELLY555-555-5554YHOME555-555-5555
从这里开始,我认为正则表达式是使用以下模式提取 CELL 数字的好方法:
"CELL[NY](\d{3}-\d{3}-\d{4})"
该模式查找单词 "CELL",后跟 'N' 或 'Y',然后是格式 ###-###-#####
中的 phone 数字。 phone 号码在捕获组中,如果找到匹配项,则可以像下面的示例所示那样访问它。
我添加了另一个 CELL 条目以显示您可以获得 XML 中的所有 CELL 编号。所以 XmlDocument
的 InnerText
属性 现在看起来像
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();
}
结果:
555-555-5554
555-555-9999
样本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' 类型代码组。第一组三个相互关联。第二组三个也相互关联,依此类推。
假设我想知道单元格 phone 的号码是多少。
当 'PhoneType' 'Value' 为 'CELL','PhonePrimaryYn' 'Value' 为 [=34= 时,我得到那个单元格 phone 编号], 我得到 '555-555-5554' 的 'PhoneNumber' 'Value'。希望你明白了。
我想知道是否有可能获得 'PhoneNumber' 值(例如单元格 phone)而不必遍历特定类型的每个节点列表组。
有人有什么想法吗?
就我个人而言,我会更改 XML 的工作方式,这样您就可以像这样在一个块中获得一个 phone 号码的所有信息
<phoneStructure>
<type>CELL</type>
<value>0123</value>
<primary>false</primary>
</phoneStructure>
然后您可以使用此 XPath select 整个 phone 结构,其中它是一个单元格 phone 或将其更改为主要的,然后从那里读取值。
//PhoneStructure[Type='Cell']
如果您需要更多帮助,请告诉我。
更新
使用 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
旧答案
当我将您的示例 XML 加载到 XmlDocument
中时,我看到它 InnerText
属性 包含以下内容:
CELLY555-555-5554YHOME555-555-5555
从这里开始,我认为正则表达式是使用以下模式提取 CELL 数字的好方法:
"CELL[NY](\d{3}-\d{3}-\d{4})"
该模式查找单词 "CELL",后跟 'N' 或 'Y',然后是格式 ###-###-#####
中的 phone 数字。 phone 号码在捕获组中,如果找到匹配项,则可以像下面的示例所示那样访问它。
我添加了另一个 CELL 条目以显示您可以获得 XML 中的所有 CELL 编号。所以 XmlDocument
的 InnerText
属性 现在看起来像
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();
}
结果:
555-555-5554
555-555-9999