Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Search XML with a LIKE or similar full search operation

I want to search an XML valued column to see if a contains a string. I don't know the schema, I want to know if the string is contained anywhere at all. I don't know if XPATH would work in this situation.

The equivalent of

Select s.Name, ts.ValueXML from table t (nolock) 
join table2 ts (nolock) on t.key_Id = ts.key_Id
join table3 s (nolock) on ts.key_Id=s.key_Id
where s.Name like '%Lab%' and ts.ValueXML  like '%PreviewDateRange%'

ERROR: Argument data type xml is invalid for argument 1 of like function.

relevant ts Table columns

ValueXml (XML(.), null)

The item I'm searching for should be an attribute. So if the above isn't possible, then anything containing that attribute would be a good alternative.

like image 653
P.Brian.Mackey Avatar asked May 06 '12 15:05

P.Brian.Mackey


People also ask

What is search XML?

The XML search grammar uses a subset of the W3 XPath language with extensions for text search. The extensions support range searches of numeric, Date, and DateTime values that are associated with an XML attribute or element. Structural elements can be used separately, or combined with free text in queries.

What is XQuery used for in XML file?

XQuery is a functional language that is used to retrieve information stored in XML format. XQuery can be used on XML documents, relational databases containing data in XML formats, or XML Databases. XQuery 3.0 is a W3C recommendation from April 8, 2014.

How do I search for a word in XML?

As a result, all tag names and content in an XML document are indexed and searchable using the Keyword field. A keyword search for either “catalog” or “title” returns the XML document. To limit your keyword search to XML documents, you can enter xml: followed by a specialized query string.


2 Answers

The simplest (but definitely not the fastest to execute) way would be to cast your column to nvarchar(max) before passing it to like:

cast(ValueXml as nvarchar(max)) like '%PreviewDateRange%'
like image 117
Sergey Kalinichenko Avatar answered Oct 26 '22 21:10

Sergey Kalinichenko


There you go:

SELECT *
FROM MyTable
WHERE MyXmlMetadataColumn.exist('//*/text()[contains(upper-case(.),upper-case("MySearchTerm"))]') = 1

This seems to work fine for me and also does not search the XML tag names as the solution provided by "dasblinkenlight".

I don't know how performant it is though.

like image 44
user2173353 Avatar answered Oct 26 '22 22:10

user2173353