Как мне построить XQuerys для включения / исключения строк в зависимости от наличия определенных тегов и атрибутов? - PullRequest
0 голосов
/ 29 августа 2009

У меня есть система аудита / ведения журнала, которая использует сырой XML для представления действий, выполняемых приложением. Я хотел бы значительно улучшить эту систему, используя столбец XML в таблице в базе данных приложения SQL Server.

Каждая строка в таблице будет содержать одну запись журнала, и каждая запись должна содержать один или несколько тегов, которые используются для описания действия в семантической форме, что позволяет мне искать способы, которые соответствуют потребностям аудита приложения, пример :

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

<deleteInvoice id="5" userId="6" /><invoice /><delete />

Мое намерение - вернуть наборы строк из этой таблицы, указав комбинации тегов и атрибутов для включения или исключения строк (например, «Включить все строки с тегом invoice, но исключить строки с атрибутом userId='7'», или « Включить все строки с тегом invoice, но исключить строки с тегом delete)

Я хочу сделать это программно, используя комбинации простой структуры фильтра для представления комбинаций тегов и атрибутов, которые я хочу, чтобы строки были либо включены, либо исключены.

Структура, которую я использую, выглядит следующим образом:

enum FilterInclusion { Include, Exclude };

public struct Filter
{
    FilterInclusion Inclusion;
    string TagName;
    string? AttributeName;
    object? AttributeValue;
}

Моя цель - принять их набор и сгенерировать запрос, который возвращает любые строки, которые соответствуют какому-либо отдельному фильтру включения, без соответствия какому-либо отдельному фильтру исключения.

Должен ли я и могу ли я закодировать эту логическую логику в сам полученный XPath или я смотрю на наличие нескольких операторов SELECT в моих выводимых запросах? Я новичок в XQuery, и любая помощь приветствуется. Спасибо!

1 Ответ

1 голос
/ 29 августа 2009

Я не уверен, что это то, что вы ищете, но для фильтрации узлов в методах XML вы используете скобки [ и ]. Например, чтобы выбрать элементы foo, но отфильтровать только те, которые имеют атрибут bar, вы бы использовали XPath, например, /foo[@bar]. Если вам нужны те, которые имеют атрибут @bar со значением 5, вы используете /foo[@bar=5]. Если вы хотите выбрать элементы foo, которые имеют child element bar, вы используете /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 в вашем посте, но там они слишком бесструктурны, чтобы создавать полезные примеры.

...