簡體   English   中英

T-SQL查找具有匹配文本的節點,並從XML字段中的兄弟節點中提取值

[英]T-SQL Find node with matching text and extract value from sibling node in XML field

我有一個xml字段的表,其內容如下:

<ContentBlock xmlns="http://corp.com/wdpr/ContentBlock">
<key xlink:href="tcm:0-133036" xlink:title="entityCard" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
<template xlink:href="tcm:0-132970" xlink:title="card-header-read-more-all-media" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
<section>
    <name xlink:href="tcm:0-132988" xlink:title="header" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <content>
        <p xmlns="http://www.w3.org/1999/xhtml">Make a Friend</p>
    </content>
</section>
<section>
    <name xlink:href="tcm:0-133110" xlink:title="readMore" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <content>
        <p xmlns="http://www.w3.org/1999/xhtml">Meet and greet friendly animals at the only petting zoo in Disney’s Animal
        Kingdom park.
     </p>
    </content>
</section>
<section>
    <name xlink:href="tcm:0-132939" xlink:title="readAll" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <content>
        <p xmlns="http://www.w3.org/1999/xhtml">Meet and greet friendly animals.
     </p>
        <p xmlns="http://www.w3.org/1999/xhtml">Pet, brush and feed domesticated creatures
     </p>
        <ul xmlns="http://www.w3.org/1999/xhtml">
            <li xmlns="http://www.w3.org/1999/xhtml">Goats</li>
        </ul>
        <p xmlns="http://www.w3.org/1999/xhtml">Handy animal brushes are available .
     </p>
        <p xmlns="http://www.w3.org/1999/xhtml">
            <strong xmlns="http://www.w3.org/1999/xhtml">Keeping Clean</strong>
            <br xmlns="http://www.w3.org/1999/xhtml"/>Guests are encouraged to cleanse.</p>
    </content>
</section>
<media>
    <name xlink:href="tcm:0-201994" xlink:title="media" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <key xlink:href="tcm:0-132952" xlink:title="170 x 96" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <image xlink:href="tcm:0-231377" xlink:title="section-01.jpg" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
</media>
</ContentBlock>

我的目標是在查詢中找到(例如)包含文本“Make a Friend”的<p> ,然后在同一<section>標記中獲取<name>元素的xlink:href。

我在這篇文章中嘗試了一些選項: 這里這里,但我沒有得到我需要的結果。

這不起作用

SELECT  a.value1,
    x.XmlCol.value('(section/content/p)[1]','VARCHAR(100)') AS SendMethod
FROM    @test a
CROSS APPLY a.AppConfig.nodes('/ContentBlock') x(XmlCol)
WHERE x.XmlCol.exist('section/content/p[contains(.,"Make a Friend")]') = 1

我怎么才能得到它?

提前致謝。 吉列爾莫。

試試這樣:

DECLARE @mockup TABLE(ID INT IDENTITY,YourXML XML);
INSERT INTO @mockup VALUES
('<ContentBlock xmlns="http://corp.com/wdpr/ContentBlock">
  <key xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:0-133036" xlink:title="entityCard" xlink:type="simple" />
  <template xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:0-132970" xlink:title="card-header-read-more-all-media" xlink:type="simple" />
  <section>
    <name xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:0-132988" xlink:title="header" xlink:type="simple" />
    <content>
      <p xmlns="http://www.w3.org/1999/xhtml">Make a Friend</p>
    </content>
  </section>
  <section>
    <name xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:0-133110" xlink:title="readMore" xlink:type="simple" />
    <content>
      <p xmlns="http://www.w3.org/1999/xhtml">Meet and greet friendly animals at the only petting zoo in Disney’s Animal
        Kingdom park.
     </p>
    </content>
  </section>
  <section>
    <name xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:0-132939" xlink:title="readAll" xlink:type="simple" />
    <content>
      <p xmlns="http://www.w3.org/1999/xhtml">Meet and greet friendly animals.
     </p>
      <p xmlns="http://www.w3.org/1999/xhtml">Pet, brush and feed domesticated creatures
     </p>
      <ul xmlns="http://www.w3.org/1999/xhtml">
        <li xmlns="http://www.w3.org/1999/xhtml">Goats</li>
      </ul>
      <p xmlns="http://www.w3.org/1999/xhtml">Handy animal brushes are available .
     </p>
      <p xmlns="http://www.w3.org/1999/xhtml">
        <strong xmlns="http://www.w3.org/1999/xhtml">Keeping Clean</strong>
        <br xmlns="http://www.w3.org/1999/xhtml" />Guests are encouraged to cleanse.</p>
    </content>
  </section>
  <media>
    <name xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:0-201994" xlink:title="media" xlink:type="simple" />
    <key xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:0-132952" xlink:title="170 x 96" xlink:type="simple" />
    <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="tcm:0-231377" xlink:title="section-01.jpg" xlink:type="simple" />
  </media>
</ContentBlock>');

- 首先我聲明一個變量來使搜索字符串動態化:

DECLARE @SearchFor VARCHAR(100)='Make a Friend';

- 您的XML在最外層元素中有一個默認命名空間。
- 什么使事情有點奇怪:元素<p>上有另一個默認命名空間
- 我們可以用說話前綴聲明這個

WITH XMLNAMESPACES(DEFAULT 'http://corp.com/wdpr/ContentBlock'
                          ,'http://www.w3.org/1999/xlink' AS xlink
                          ,'http://www.w3.org/1999/xhtml' AS InnerDflt )
SELECT YourXML.value('(/ContentBlock/section[(content/InnerDflt:p/text())[1]=sql:variable("@SearchFor")]/name/@xlink:href)[1]','nvarchar(max)') 
FROM @mockup

查詢運行如下:

<ContentBlock>開始。 查找<section><content>下面的<p>text()是搜索字符串。 重要提示:在此階段,我們仍然處於<section>的級別。 所以我們可以用<name>繼續XPath並在那里找到屬性。

Shnugo偷走了我的雷聲但是我仍然發布了我放在一起的東西,因為它也會起作用並展示一些技巧(例如*:因為你懶得添加正確的命名空間語法);)。 我要提到使用sql:variable將一個SQL變量傳遞給你的XPath表達式 - shnugo的帖子演示了如何做到這一點(它在我發布的內容中缺失)。

-- bonus sample data
DECLARE @xml XML = 
'<ContentBlock xmlns="http://corp.com/wdpr/ContentBlock">
<key xlink:href="tcm:0-133036" xlink:title="entityCard" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
<template xlink:href="tcm:0-132970" xlink:title="card-header-read-more-all-media" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
<section>
    <name xlink:href="tcm:0-132988" xlink:title="header" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <content>
        <p xmlns="http://www.w3.org/1999/xhtml">Make a Friend</p>
    </content>
</section>
<section>
    <name xlink:href="tcm:0-133110" xlink:title="readMore" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <content>
        <p xmlns="http://www.w3.org/1999/xhtml">Meet and greet friendly animals at the only petting zoo in Disney’s Animal
        Kingdom park.
     </p>
    </content>
</section>
<section>
    <name xlink:href="tcm:0-132939" xlink:title="readAll" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <content>
        <p xmlns="http://www.w3.org/1999/xhtml">Meet and greet friendly animals.</p>
        <p xmlns="http://www.w3.org/1999/xhtml">Pet, brush and feed domesticated creatures
     </p>
        <ul xmlns="http://www.w3.org/1999/xhtml">
            <li xmlns="http://www.w3.org/1999/xhtml">Goats</li>
        </ul>
        <p xmlns="http://www.w3.org/1999/xhtml">Handy animal brushes are available .
     </p>
        <p xmlns="http://www.w3.org/1999/xhtml">
            <strong xmlns="http://www.w3.org/1999/xhtml">Keeping Clean</strong>
            <br xmlns="http://www.w3.org/1999/xhtml"/>Guests are encouraged to cleanse.</p>
    </content>
</section>
<media>
    <name xlink:href="tcm:0-201994" xlink:title="media" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <key xlink:href="tcm:0-132952" xlink:title="170 x 96" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
    <image xlink:href="tcm:0-231377" xlink:title="section-01.jpg" xlink:type="simple" xmlns:xlink="http://www.w3.org/1999/xlink"/>
</media>
</ContentBlock>';

DECLARE @test TABLE (someId INT IDENTITY, AppConfig XML);
INSERT @test (AppConfig) VALUES (@xml),(CAST(REPLACE(REPLACE(CAST(@xml AS VARCHAR(8000)),
  'Make a Friend','xxx'),'Keeping Clean','Make a Friend') AS XML));

-- SOLUTION
WITH XMLNAMESPACES ('http://www.w3.org/1999/xlink' AS xlink)
SELECT t.someId, href = cb.x.value('(../*:name/@xlink:href)[1]', 'varchar(8000)')
FROM @test AS t
CROSS APPLY t.AppConfig.nodes('*:ContentBlock/*:section/*:content') AS cb(x)
WHERE cb.x.exist('*:p[contains(.,"Make a Friend")]') = 1;

返回:

someId      href
----------- -------------
1           tcm:0-132988
2           tcm:0-132939

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM