I have a xpath= //*[#id='00QE000000gQ9fv_ACTION_COLUMN']/a[2]/span
in this xpath 00QE000000gQ9fv is dynamic and _ACTION_COLUMN remains same.
I stored 00QE000000gQ9fv in a String variable as recordId i.e
String recordId = 00QE000000gQ9fv
Now i want a xpath which contains recordId variable.
your xpath will be - //*[contains(#id,'_ACTION_COLUMN')]/a[2]/span
Make sure _ACTION_COLUMN is unique or is the first element in your html so that u grab hold of the right element.
Edit 1 according to your comment.
Try this: //*[contains(#id,'"+recordId +"')]/a[2]/span
or
//*[#id='"+ recordId +"_ACTION_COLUMN']/a[2]/span
Related
I have a query with xpath. The values in the xpath is filled dynamically.
Query:
SELECT app_prof.pk_szid, app_prof.xmldata
FROM tblappprofile AS app_prof
WHERE 'Self' =
CAST((xpath('/ApplicationProfile/ComponentIDs/ComponentID[#Family="Core"]/text()', xmldata))[1] AS TEXT)
For preparedStatement:
SELECT app_prof.pk_szid, app_prof.xmldata
FROM tblappprofile AS app_prof
WHERE ? =
CAST((xpath('/ApplicationProfile/ComponentIDs/ComponentID[#Family= ? ]/text()', xmldata))[1] AS TEXT)
When I use,
preparedStatement.setString(1, "Self");
preparedStatement.setString(2, "Core");
results in org.postgresql.util.PSQLException: The column index is out of range: 2, number of columns: 1
The 'Self' is filled correctly. ? in attribute is not recognized. How to use PreparedStatement for attributes in Xpath?
Question marks inside string literals are not considered as parameter placeholders.
You need to pass the whole XPath expression as a parameter:
WHERE ? = CAST((xpath(?, xmldata))[1] AS TEXT)
another option is to dynamically create a string using the format() function:
where ? = CAST((xpath(format('/ApplicationProfile/ComponentIDs/ComponentID[#Family="%s"]/text()',?), xmldata))[1]
That way you can pass the value for #Familiy as a parameter and still keep the XPath inside the SQL if you want.
TSQL - Need to query a database column which is populated by XML.
The Database has an iUserID column with an Application ID and VCKey
TxtValue is the Column name and the contained Data is similar to this
<BasePreferencesDataSet xmlns="http://tempuri.org/BasePreferencesDataSet.xsd">
<ViewModesTable>
<iViewID>1</iViewID>
</ViewModesTable>
<ViewMode_PreferenceData>
<iViewID>1</iViewID>
<iDataID>0</iDataID>
<strValue>False</strValue>
</ViewMode_PreferenceData>
<ViewMode_PreferenceData>
<iViewID>1</iViewID>
<iDataID>5</iDataID>
<strValue>True</strValue>
</ViewMode_PreferenceData>
<ViewMode_PreferenceData>
<iViewID>1</iViewID>
<iDataID>6</iDataID>
<strValue>True</strValue>
</ViewMode_PreferenceData>
<ViewMode_PreferenceData>
<iViewID>1</iViewID>
<iDataID>4</iDataID>
<strValue>False</strValue>
I want to be able to identify any iUserID in which the StrValue for iDataID's 5 and 6 are not set to True.
I have attempted to use a txtValue Like % statement but even if I copy the contents and query for it verbatim it will not yield a result leading me to believe that the XML data cannot be queried in this manner.
Screenshot of Select * query for this DB for reference
You can try XML-method .exist() together with an XPath with predicates:
WITH XMLNAMESPACES(DEFAULT 'http://tempuri.org/BasePreferencesDataSet.xsd')
SELECT *
FROM YourTable
WHERE CAST(txtValue AS XML).exist('/BasePreferencesDataSet
/ViewMode_PreferenceData[iDataID=5 or iDataID=6]
/strValue[text()!="True"]')=1;
The namespace-declaration is needed to address the elements without a namespace prefix.
The <ViewMode_PreferenceData> is filtered for the fitting IDs, while the <strValue> is filtered for a content !="True". This will return any data row, where there is at least one entry, with an ID of 5 or 6 and a value not equal to "True".
So without sample data (including tags; sorry you're having trouble with that) it's tough to craft the complete query, but what you're looking for is XQuery, specifically the .exists method in T-SQL.
Something like
SELECT iUserID
FROM tblLocalUserPreferences
WHERE iApplicationID = 30
AND vcKey='MonitorPreferences'
AND (txtValue.exist('//iDataID[text()="5"]/../strValue[text()="True"]') = 0
OR txtValue.exist('//iDataID[text()="6"]/../strValue[text()="True"]')=0)
This should return all userID's where either iDataID 5 or 6 do NOT contain True. In other words, if both are true, you won't get that row back.
I have the next simple query :
SELECT code, description
FROM table
WHERE code in ( #list# )
The list is created from an XML feed with listAppend():
<cfset list= listAppend(list, data.data1[i].xmltext )>
<cfset qualifiedList1 = ListQualify(list, "'")>
With listQualify I wrap every element from the list in quotation marks for the query. The problem is that when I run the query, I don't get any results back.
If I dump the list the query look like this :
SELECT code, description
FROM table
WHERE code in ('''BG/NN1'',''BG/NL2'',''BG/NN3'',''BG/NN4'',''BG/NN5''')
Any ideas on how can fix this problem?
Update 1:
I've fixed the problem.The problem was with ListQualify(list, "'")> Because list Qualify wraps every element in quotes the list attribute from cfqueryparam didn't recognized any of the values.Thank you!
Is there a way to check that value of an element in the XML field has an empty size using SQLXML? Consider I have the following data in the column Conf of the table Test:
<Conf>
<UserData>
<data type="str" value="" />
</UserData>
</Conf>
I can check that data exists by using the following SQL request:
SELECT Test.Conf.exist('/Conf/UserData/data') FROM Test;
But how can I check that data has an empty value? It could be something like the following, but it doesn't work:
SELECT Test.Conf.value('(/Conf/UserData/data/#value)[1]', 'nvarchar(max)')='' FROM Test;
My final solution is to use the following SQL statement:
SELECT Test.Conf.value('string-length(/Conf[1]/UserData[1]/data[1]/#value)', 'int') FROM Test;
Using XPath 1.0. string(#someattribute) test should return false if empty. I know nothing about SQLXML, but it will work if you can use a control sequence.
Possibly this will work.
SELECT Test.Conf.exist('data(/Conf/UserData/data[#value=''''])') FROM Test;
This checks to see if a data element with #value = '' exists.
The problem is not with XPath but with TSQL syntax.
XML.Exist returns a BIT datatype, indicating whether it exists. SQL Server has no native BOOLEAN datatype (a real true/false).
So, your query should have been
SELECT CASE WHEN Test.Conf.value('(/Conf/UserData/data/#value)[1]', 'nvarchar(max)')=''
THEN 1 ELSE 0 END
FROM Test;
We have a source XML file that has an address node, and each node is supposed to have a zip_code node beneath in order to validate. We received a file that failed the schema validation because at least one node was missing it's zip_code (there were several thousand addresses in the file).
We need to find the elements that do not have a zip code, so we can repair the file and send an audit report to the source.
--declare #x xml = bulkcolumn from openrowset(bulk 'x:\file.xml',single_blob) as s
declare #x xml = N'<addresses>
<address><external_address_id>1</external_address_id><zip_code>53207</zip_code></address>
<address><external_address_id>2</external_address_id></address>
</addresses>'
declare #t xml = (
select #x.query('for $a in .//address
return
if ($a/zip_code)
then <external_address_id />
else $a/external_address_id')
)
select x.AddressID.value('.', 'int') AddressID
from #t.nodes('./external_address_id') x(AddressID)
where x.AddressID.value('.', 'int') > 0
GO
Really, it's the where clause that bugs me. I feel like I'm depending on a cast for a null value to 0, and it works, but I'm not really sure that it should. I tried a few variations with the .exist function, but I couldn't get the correct result.
If you just want to ensure that you are selecting address elements that have a zip_code element, then adjust your XPATH to include that criteria in a predicate filter:
/addresses/address[zip_code]
If you also want to ensure that the zip_code element also has a value, use a predicate filter for the zip_node to select those that have text() nodes:
/addresses/address[zip_code[text()]]
EDIT:
Actually, I'm looking for the
opposite. I need to identify the nodes
that don't have a zip, so we can
manually correct the source data.
So, if you want to identify all of the address elements that do not have a zip_code, you can specify it in the XPATH like this:
/addresses/address[not(zip_code)]
If you just want to locate those nodes that are missing their <zip_code> element, you could use something like this:
SELECT
ADRS.ADR.value('(external_address_id)[1]', 'int') as 'ExtAdrID'
FROM
#x.nodes('/addresses/address') as ADRS(ADR)
WHERE
ADRS.ADR.exist('zip_code') = 0
It uses the built-in .exist() method in XQuery to check the existence of a subnode inside an XML node.