代码之家  ›  专栏  ›  技术社区  ›  Dan Rigby

.NET、XML和Regex-如何匹配特定集合项?

  •  0
  • Dan Rigby  · 技术社区  · 15 年前

    因此,我有一个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中编写一个regex,它与Subelement2为空的任何CollectionItem(本例中的中间CollectionItem)相匹配。

    到目前为止,我有以下regex(启用单线模式):

    <CollectionItem>.+?<SubElement2 />.+?</CollectionItem>
    

    问题是,它通过第二个集合项的关闭来匹配第一个集合项的打开。我知道为什么要这样做,但我不知道如何修改regex使其只匹配中心集合项。

    编辑:关于为什么Regex与其他东西不同:

    1. 为了简单起见,我试图在文本编辑器中修改文件。
    2. 在我不知道如何在regex中完成它之后,我想知道为了学习是否可以(以及如何)完成它。

    谢谢!

    3 回复  |  直到 15 年前
        1
  •  2
  •   Tim Pietzcker    15 年前

    你可以使用

    <CollectionItem>((?!<CollectionItem>).)+?<SubElement2 />.+?</CollectionItem>
    

    这就确保了 <CollectionItem> 介于起始标签和 <SubElement2 /> 标签。

        2
  •  5
  •   Jon Skeet    15 年前

    为什么要使用正则表达式?您有一个非常好的域模型(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));
    
        3
  •  3
  •   David M    15 年前

    这是XML—为什么要用regex来做这个?xpath是否更有意义?