[英]How to return the value that exists in SQL Server XPath?
There is a question somewhere on Stackoverflow, although i cannot find it now, that reminded the poster that .value
does not return the value that .exist
s. 在Stackoverflow上的某个地方有一个问题,尽管我现在找不到,但提醒发布者
.value
不会返回.exist
s的值。
That is because .value
is always written as asking for the [1]
item, where .exist
looks everywhere. 这是因为
.value
始终写为要求[1]
项,而.exist
到处都是。
Given a hypothetical xml document containing two customers: 给定一个假设的xml文档,其中包含两个客户:
<Customer>
<Name>Ian Boyd</Name>
<IDInfo>
<IDType>1</IDType>
</IDInfo>
</Customer>
<Customer>
<Name>Kirsten</Name>
<IDInfo>
<IDType>3</IDType>
<IDOtherDescription>Firearms Certificate</IDOtherDescription>
</IDInfo>
</Customer>
i want to return the Name
, IDType
, and IDOtherDescription
for any customers who have an IDType of 3
(Other): 我想为IDType为
3
(其他)的任何客户返回Name
, IDType
和IDOtherDescription
:
DECLARE @xml XML;
SET @xml =
'<Customer>
<Name>Ian Boyd</Name>
<IDInfo>
<IDType>1</IDType>
</IDInfo>
</Customer>
<Customer>
<Name>Kirsten</Name>
<IDInfo>
<IDType>3</IDType>
<IDOtherDescription>Firearms Certificate</IDOtherDescription>
</IDInfo>
</Customer>'
--Wrap it up in a table, cause it makes it look more like my real situation
;WITH BatchReports AS (
SELECT @xml AS BatchFileXml
)
SELECT
BatchFileXml.value('(//Name)[1]', 'varchar(50)') AS Name,
BatchFileXml.value('(//IDType)[1]', 'varchar(50)') AS IDType,
BatchFileXml.value('(//IDOtherDescription)[1]', 'varchar(50)') AS IDOtherDescription,
*
FROM BatchReports
--WHERE BatchFileXml.value('(//IDType)[1]', 'varchar(50)') = '3'
WHERE BatchFileXml.exist('//IDType[text()="3"]')=1
Since the .exist
is satisfied, it returns a row: 由于
.exist
满足 ,它返回一行:
Name IDType IDOtherDescription
-------- ------ --------------------
Ian Boyd 1 Firearms Certificate
Except that's not what i wanted. 除非那不是我想要的。 I wanted the values where
IDType = 3
. 我想要
IDType = 3
的值。
Things get even more complicated, where there are multiple IDType
entries: 在有多个
IDType
条目的情况下,事情变得更加复杂:
<Customer>
<Name>Ian Boyd</Name>
<IDInfo>
<IDType>1</IDType>
</IDInfo>
</Customer>
<Customer>
<Name>Kirsten</Name>
<IDInfo>
<IDType>1</IDType>
</IDInfo>
<IDInfo>
<IDType>2</IDType>
</IDInfo>
<IDInfo>
<IDType>4</IDType>
</IDInfo>
<IDInfo>
<IDType>3</IDType>
<IDOtherDescription>Firearms Certificate</IDOtherDescription>
</IDInfo>
</Customer>
And even more complicated when you can find /IDInfo
nodes in other levels: 在其他级别可以找到
/IDInfo
节点时,甚至更加复杂:
<Customer>
<Name>Ian Boyd</Name>
<IDInfo>
<IDType>1</IDType>
</IDInfo>
<ThirdPartyInfo>
<IDInfo>
<IDType>3</IDType>
<IDOtherDescription>Sherrif Badge</IDOtherDescription>
</IDInfo>
</ThirdPartyInfo>
</Customer>
<Customer>
<Name>Kirsten</Name>
<IDInfo>
<IDType>1</IDType>
</IDInfo>
<IDInfo>
<IDType>2</IDType>
</IDInfo>
<IDInfo>
<IDType>4</IDType>
</IDInfo>
<IDInfo>
<IDType>3</IDType>
<IDOtherDescription>Firearms Certificate</IDOtherDescription>
</IDInfo>
</Customer>
The end result is the same. 最终结果是相同的。 I need a query to return the
values
that exist
: 我需要一个查询以返回
exist
的values
:
Name IDType IDOtherDescription
-------- ------ --------------------
Ian Boyd 3 Sherrif Badge
Kirsten 3 Firearms Certificate
When i designed the system two years ago, and chose to use XML
data type, i figured it would be useful when there's an emergency. 当我两年前设计系统并选择使用
XML
数据类型时,我认为在紧急情况下它将很有用。 I can use some XPath to filter through the raw xml. 我可以使用一些XPath来过滤原始xml。 I forgot how impossible XPath, and XPath in SQL Server is.
我忘记了XPath和SQL Server中的XPath是多么不可能。 Four hours of staring at documentation and web-sites;
盯着文档和网站四个小时; i'm hungry and tired.
我饿又累。
Here is the query you can try: 您可以尝试以下查询:
;WITH BatchReports AS (
SELECT @xml AS BatchFileXml
)
SELECT a.BatchXml.value('(Name)[1]', 'varchar(50)') AS Name,
a.BatchXml.value('(IDInfo/IDType)[1]', 'varchar(50)') AS IDType,
a.BatchXml.value('(IDInfo/IDOtherDescription)[1]', 'varchar(50)') AS IDOtherDescription
FROM BatchReports b
CROSS APPLY b.BatchFileXml.nodes('Customer') A(BatchXml)
WHERE a.BatchXml.exist('IDInfo/IDType[text()=3]')=1
and here is the query which retrieve necessary information form all of the XMLs. 这是从所有XML中检索必要信息的查询。
;WITH BatchReports AS (
SELECT @xml AS BatchFileXml
)
SELECT A.BatchXml.value('(Name)[1]', 'varchar(50)') AS Name,
B.BatchXml.value('(IDType)[1]', 'varchar(50)') AS IDType,
B.BatchXml.value('(IDOtherDescription)[1]', 'varchar(50)') AS IDOtherDescription
FROM BatchReports X
CROSS APPLY X.BatchFileXml.nodes('Customer') A(BatchXml)
CROSS APPLY A.BatchXml.nodes('//IDInfo') B(BatchXml)
WHERE A.BatchXml.exist('IDInfo/IDType[text()=3]')=1
AND B.BatchXml.exist('IDType[text()=3]')=1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.