如何使用 XQuery 根据属性过滤 XML 数据
How to filter XML data based on an attribute using XQuery
鉴于下面的XML结构,我需要过滤掉所有<questionSubType/>
值等于ABC
和<option subType=""/>
的节点] 属性等于 001
:
<questions>
<question>
<text>Some text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
<option subType="001">
<text>N</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
<option subType="002">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some more text</text>
<questionType></questionType>
<questionSubType>DEF</questionSubType>
<options>
<option subType="001">
<text>Single</text>
<mappedCodes>
<code>PL0157</code>
</mappedCodes>
</option>
<option subType="001">
<text>Married</text>
<mappedCodes>
<code>PD0241</code>
</mappedCodes>
</option>
<option subType="002">
<text>Single</text>
<mappedCodes>
<code>PL1157</code>
</mappedCodes>
</option>
<option subType="002">
<text>Married</text>
<mappedCodes>
<code>PD1241</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some last text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>T</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
<option subType="002">
<text>V</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
</options>
</question>
</questions>
我尝试了以下操作,但这只会根据 <questionSubType/>
值过滤 XML,因为我不确定如何继续查询 <option/>
节点:
DECLARE
@subType varchar(5) = '001'
, @questionSubType varchar(5) = 'ABC'
SET @XmlOutput = (
SELECT
1 as Tag
, null as Parent
, CONVERT(nvarchar(max), F.N.query('./*')) as [question!1!!XML]
FROM [MyTable] T
CROSS APPLY T.[Configuration].nodes('//question') F(N)
WHERE
F.N.value('(//questionSubType/text())[1]', 'varchar(100)') = @questionSubType
FOR XML EXPLICIT, ROOT('questions')
)
SELECT @XmlOutput as [Configuration]
所以最后,我的输出应该是这样的:
<questions>
<question>
<text>Some text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
<option subType="001">
<text>N</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some last text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>T</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
</options>
</question>
</questions>
如有任何帮助,我们将不胜感激。
这是 XQuery
对你的拯救:
DECLARE @xml XML=
N'<questions>
<question>
<text>Some text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
<option subType="001">
<text>N</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
<option subType="002">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some more text</text>
<questionType></questionType>
<questionSubType>DEF</questionSubType>
<options>
<option subType="001">
<text>Single</text>
<mappedCodes>
<code>PL0157</code>
</mappedCodes>
</option>
<option subType="001">
<text>Married</text>
<mappedCodes>
<code>PD0241</code>
</mappedCodes>
</option>
<option subType="002">
<text>Single</text>
<mappedCodes>
<code>PL1157</code>
</mappedCodes>
</option>
<option subType="002">
<text>Married</text>
<mappedCodes>
<code>PD1241</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some last text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>T</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
<option subType="002">
<text>V</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
</options>
</question>
</questions>';
--声明你的变量
DECLARE @subType varchar(5) = '001'
,@questionSubType varchar(5) = 'ABC';
-- XQuery
将 运行 通过你的 XML 并添加给定类型的所有问题,然后添加除 <options>
之外的所有内部节点。最后一个节点再次添加过滤谓词:
SELECT @xml.query
('<questions>
{
for $q in /questions/question[(questionSubType/text())[1]=sql:variable("@questionSubType")]
return
<question>
{
$q/*[local-name()!="options"]
}
{
$q/options/option[@subType=sql:variable("@subType")]
}
</question>
}
</questions>
');
鉴于下面的XML结构,我需要过滤掉所有<questionSubType/>
值等于ABC
和<option subType=""/>
的节点] 属性等于 001
:
<questions>
<question>
<text>Some text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
<option subType="001">
<text>N</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
<option subType="002">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some more text</text>
<questionType></questionType>
<questionSubType>DEF</questionSubType>
<options>
<option subType="001">
<text>Single</text>
<mappedCodes>
<code>PL0157</code>
</mappedCodes>
</option>
<option subType="001">
<text>Married</text>
<mappedCodes>
<code>PD0241</code>
</mappedCodes>
</option>
<option subType="002">
<text>Single</text>
<mappedCodes>
<code>PL1157</code>
</mappedCodes>
</option>
<option subType="002">
<text>Married</text>
<mappedCodes>
<code>PD1241</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some last text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>T</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
<option subType="002">
<text>V</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
</options>
</question>
</questions>
我尝试了以下操作,但这只会根据 <questionSubType/>
值过滤 XML,因为我不确定如何继续查询 <option/>
节点:
DECLARE
@subType varchar(5) = '001'
, @questionSubType varchar(5) = 'ABC'
SET @XmlOutput = (
SELECT
1 as Tag
, null as Parent
, CONVERT(nvarchar(max), F.N.query('./*')) as [question!1!!XML]
FROM [MyTable] T
CROSS APPLY T.[Configuration].nodes('//question') F(N)
WHERE
F.N.value('(//questionSubType/text())[1]', 'varchar(100)') = @questionSubType
FOR XML EXPLICIT, ROOT('questions')
)
SELECT @XmlOutput as [Configuration]
所以最后,我的输出应该是这样的:
<questions>
<question>
<text>Some text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
<option subType="001">
<text>N</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some last text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>T</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
</options>
</question>
</questions>
如有任何帮助,我们将不胜感激。
这是 XQuery
对你的拯救:
DECLARE @xml XML=
N'<questions>
<question>
<text>Some text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
<option subType="001">
<text>N</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
<option subType="002">
<text>Y</text>
<mappedCodes>
<code>1</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some more text</text>
<questionType></questionType>
<questionSubType>DEF</questionSubType>
<options>
<option subType="001">
<text>Single</text>
<mappedCodes>
<code>PL0157</code>
</mappedCodes>
</option>
<option subType="001">
<text>Married</text>
<mappedCodes>
<code>PD0241</code>
</mappedCodes>
</option>
<option subType="002">
<text>Single</text>
<mappedCodes>
<code>PL1157</code>
</mappedCodes>
</option>
<option subType="002">
<text>Married</text>
<mappedCodes>
<code>PD1241</code>
</mappedCodes>
</option>
</options>
</question>
<question>
<text>Some last text</text>
<questionType></questionType>
<questionSubType>ABC</questionSubType>
<options>
<option subType="001">
<text>T</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
<option subType="002">
<text>V</text>
<mappedCodes>
<code>2</code>
</mappedCodes>
</option>
</options>
</question>
</questions>';
--声明你的变量
DECLARE @subType varchar(5) = '001'
,@questionSubType varchar(5) = 'ABC';
-- XQuery
将 运行 通过你的 XML 并添加给定类型的所有问题,然后添加除 <options>
之外的所有内部节点。最后一个节点再次添加过滤谓词:
SELECT @xml.query
('<questions>
{
for $q in /questions/question[(questionSubType/text())[1]=sql:variable("@questionSubType")]
return
<question>
{
$q/*[local-name()!="options"]
}
{
$q/options/option[@subType=sql:variable("@subType")]
}
</question>
}
</questions>
');