代码之家  ›  专栏  ›  技术社区  ›  jscharf

我如何构建XQuery,以基于特定标记和属性的存在来包含/排除行?

  •  0
  • jscharf  · 技术社区  · 15 年前

    我有一个审计/日志记录系统,它使用原始XML来表示应用程序执行的操作。我想通过在应用程序的SQL Server数据库中的表中使用XML列来大大改进这个系统。

    表中的每一行将包含一个日志条目,每个条目应包含一个或多个标记,这些标记用于以语义方式描述操作,使我能够以符合应用程序审核需求的方式进行搜索,例如:

    <updateInvoice id="5" userId="7" /><fieldUpdate name="InvoiceDate" /><invoice /><update />
    
    <deleteInvoice id="5" userId="6" /><invoice /><delete />
    

    我的目的是通过指定标记和属性的组合从该表中返回行集,以包含或排除行(例如,“包含带有标记的所有行 invoice 但排除具有该属性的行 userId='7' “,或”包含带有标记的所有行 发票 但不包括带有标记的行 delete )

    我希望通过使用简单筛选结构的组合来编程实现这一点,以表示我希望包含或排除行的标记和属性的组合。

    我使用的结构如下:

    enum FilterInclusion { Include, Exclude };
    
    public struct Filter
    {
        FilterInclusion Inclusion;
        string TagName;
        string? AttributeName;
        object? AttributeValue;
    }
    

    我的目标是接受其中的一组,并生成一个查询,该查询返回与任何单个包含筛选器匹配的任何行,而不匹配任何单个排除筛选器。

    我应该并且可以将这个布尔逻辑编码到生成的xpath本身中,还是希望在输出的查询中有多个select语句?我刚接触XQuery,非常感谢您的帮助。谢谢!

    1 回复  |  直到 15 年前
        1
  •  1
  •   Remus Rusanu    15 年前

    我不确定这是否是您要查找的内容,但要筛选XML方法中的节点,请使用括号 [ ] . 例如选择元素 foo 但是只过滤那些具有属性的 bar 您可以使用类似xpath的 /foo[@bar] . 如果你想要那些有属性的 @bar 使用值5 /foo[@bar=5] . 如果要选择元素 有一个 小孩 要素 酒吧 你用 /foo[bar] .

    declare @t table (x xml);
    insert into @t (x) values 
    (N'<foo bar="abc"/>');
    insert into @t (x) values 
    (N'<foo bar="5"/>');
    insert into @t (x) values 
    (N'<foo id="1"><bar id="2"/></foo>');
    select * from @t;
    
    select c.value(N'@bar', N'varchar(max)') 
    from @t cross apply x.nodes(N'/foo[@bar]') t(c)
    
    select c.value(N'@bar', N'varchar(max)') 
    from @t cross apply x.nodes(N'/foo[@bar=5]') t(c)
    select c.value(N'@id', N'int') 
    from @t cross apply x.nodes(N'/foo[bar]') t(c)
    

    我试图在您的文章中的XML片段中展示这些示例,但是这些示例太无结构,无法生成有用的示例。