t-sql: dynamically filter XML on multiple conditions?

TrevsRevenge

New Member
I'm trying to find a way to do a accept/reject on an XML string, by joining it to a table of conditions. I have one "filter" working now, but want to write it so that it can filter 2 or more. Here's code that matches one of the two. If either matches, it will filter the string.What I want to do is make it so it has to match BOTH, while still leaving the option for single-condition\[code\]CREATE TABLE #filter (exclusion_type CHAR(1), excluded_value varchar(10))INSERT INTO #filter VALUES ('B','boy')INSERT INTO #filter VALUES ('C','cat')DECLARE @data XMLSELECT @data = 'http://stackoverflow.com/questions/12308099/<A><B>boy</B><C>cat</C></A>'SELECT * FROM (SELECT CONVERT(VARCHAR(128),node.query('fn:local-name(.)')) AS NodeName, CONVERT(VARCHAR(MAX),node.query('./text()')) AS NodeValueFROM @data.nodes(N'//*') T(node))xml_shredIF NOT EXISTS (SELECT * FROM (SELECT CONVERT(VARCHAR(128),node.query('fn:local-name(.)')) AS NodeName, CONVERT(VARCHAR(MAX),node.query('./text()')) AS NodeValueFROM @data.nodes(N'//*') T(node)) xml_shredINNER JOIN #filterON (nodename = exclusion_type AND nodevalue LIKE excluded_value))select 'record would be inserted 'ELSE select 'record was filtered'\[/code\]Here's how I currently have it to filter both. Ugly and non-expandable.\[code\]IF NOT EXISTS (SELECT * FROM (SELECT CONVERT(VARCHAR(128),node.query('fn:local-name(.)')) AS NodeName, CONVERT(VARCHAR(MAX),node.query('./text()')) AS NodeValueFROM @data.nodes(N'//*') T(node)) xml_shredINNER JOIN #filterON (nodename = exclusion_type AND nodevalue LIKE excluded_value))--combination filters don't easily work within that xml_shredand not( @data.value('(/A/B)[1]', 'varchar(128)') = 'boy' AND @data.value('(/A/C)[1]', 'varchar(128)')='cat' )select 'record would be inserted 'ELSE select 'record was filtered'\[/code\]My only other ideas:
  • some sort of GUID that would link records in the #filter table together, and then inner join on a GROUP BY of #filtertable, grouping by the GUID and using the SUM to match the number of records.
  • use semicolons to split the #filter rows, then use a CTE or something to fake a hierarchy and work from there.
 
Back
Top