所以我有一个xml文件,其中包含以下简化的xml文件内容:
<CollectionItems>
<CollectionItem>
<Element1>Value1</Element1>
<Element2>
<SubElement1>SubValue1</SubElement1>
<SubElement2>SubValue2</SubElement2>
<SubElement3>SubValue3</SubElement3>
</Element2>
<Element3>Value3</Element3>
</CollectionItem>
<CollectionItem>
<Element1>Value1</Element1>
<Element2>
<SubElement1>SubValue1</SubElement1>
<SubElement2 />
<SubElement3>SubValue3</SubElement3>
</Element2>
<Element3>Value3</Element3>
</CollectionItem>
<CollectionItem>
<Element1>Value1</Element1>
<Element2>
<SubElement1>SubValue1</SubElement1>
<SubElement2>SubValue2</SubElement2>
<SubElement3>SubValue3</SubElement3>
</Element2>
<Element3>Value3</Element3>
</CollectionItem>
</CollectionItems>
我试图在.Net中编写一个正则表达式,它匹配SubElement2为空的任何CollectionItem(本例中为CollectionItem)。
到目前为止,我有以下正则表达式(启用SingleLine模式):
<CollectionItem>.+?<SubElement2 />.+?</CollectionItem>
问题是它通过第二个CollectionItem的关闭匹配第一个CollectionItem的开头。我理解为什么会这样做,但我不知道如何修改正则表达式使它只匹配中心CollectionItem。
编辑:至于为什么正则表达式与其他东西相反:
谢谢!
答案 0 :(得分:5)
为什么要尝试使用正则表达式?你有一个非常好的域模型(XML) - 为什么不搜索它呢?例如,在LINQ to XML中:
var collectionsWithEmptySubElement2 =
document.Descendants("SubElement2")
.Where(x => x.IsEmpty)
.Select(x => x.Ancestors("CollectionItem").FirstOrDefault());
或
var collectionsWithEmptySubElement2 =
document.Descendants("CollectionItem")
.Where(x => x.Descendants("SubElement2").Any(sub => sub.IsEmpty));
答案 1 :(得分:3)
这是XML - 为什么要尝试使用Regex? XPath不会更有意义吗?
答案 2 :(得分:2)
您可以使用
<CollectionItem>((?!<CollectionItem>).)+?<SubElement2 />.+?</CollectionItem>
这可确保在起始标记与<CollectionItem>
标记之间不再有<SubElement2 />
。