使用sql获取节点的绝对位置

时间:2010-02-05 18:47:20

标签: sql xml tsql

我有一本圣经的xml文件

as

<bookcoll>
<book>
<bktshort>Matthew</bktshort>
<chapter><chtitle>Chapter 1</chtitle>
<v>The book of the generation of Jesus Christ, the son of David, the son of Abraham.
</v>
<v>Abraham begat Isaac; and Isaac begat Jacob; and Jacob begat Judas and his brethren;
</v>
..
</chapter>
<chapter><chtitle>Chapter 2</chtitle>
<v>Now when Jesus was born in Bethlehem of Judaea in the days of Herod the king, behold, there came wise men from the east to Jerusalem,
</v>

我想保留<v>个节点的总nuber的行号。

此语句重置每个章节点的编号

select 
    Chapter.value('../../bktshort[1]', 'varchar(200)'),
    Replace(Chapter.value('../chtitle[1]', 'varchar(200)'),'Chapter ', ''),
    p.number,
    Chapter.value('.','varchar(max)')
from
    master..spt_values p
CROSS APPLY
    @xml.nodes('/bookcoll/book/chapter/v[position()=sql:column("number")]') T(Chapter)
--where p.type = 'p'
order by 
Chapter.value('../../bktshort[1]', 'varchar(200)'),
Replace(Chapter.value('../chtitle[1]', 'varchar(200)'),'Chapter ', ''),
    p.number

所以而不是

Matthew 1   23  Behold, a virgin shall be with child, and shall bring forth a son, and they shall call his name Emmanuel, which being interpreted is, God with us.   
Matthew 1   24  Then Joseph being raised from sleep did as the angel of the Lord had bidden him, and took unto him his wife:   
Matthew 1   25  And knew her not till she had brought forth her firstborn son: and he called his name JESUS.   
Matthew 2   1   Now when Jesus was born in Bethlehem of Judaea in the days of Herod the king, behold, there came wise men from the east to Jerusalem,   
Matthew 2   2   Saying, Where is he that is born King of the Jews? for we have seen his star in the east, and are come to worship him.   

我想要

Matthew 1   23  Behold, a virgin shall be with child, and shall bring forth a son, and they shall call his name Emmanuel, which being interpreted is, God with us.   
Matthew 1   24  Then Joseph being raised from sleep did as the angel of the Lord had bidden him, and took unto him his wife:   
Matthew 1   25  And knew her not till she had brought forth her firstborn son: and he called his name JESUS.   
Matthew 2   <b>26</b>   Now when Jesus was born in Bethlehem of Judaea in the days of Herod the king, behold, there came wise men from the east to Jerusalem,   
Matthew 2   <b>27</b>    Saying, Where is he that is born King of the Jews? for we have seen his star in the east, and are come to worship him.   

旁注我知道spt_values表不够大,必须使用本地表。

2 个答案:

答案 0 :(得分:2)

也许这会激发一些想法?

DECLARE @xml XML = '<bookcoll> 
                        <book> 
                            <bktshort>Matthew</bktshort> 
                            <chapter>
                                <chtitle>Chapter 1</chtitle> 
                                <v>The book of the generation of Jesus Christ, the son of David, the son of Abraham. </v> 
                                <v>Abraham begat Isaac; and Isaac begat Jacob; and Jacob begat Judas and his brethren; </v>
                             </chapter> 
                            <chapter>
                                <chtitle>Chapter 2</chtitle> 
                                <v>Now when Jesus was born in Bethlehem of Judaea in the days of Herod the king, behold, there came wise men from the east to Jerusalem, </v>
                                </chapter>
                                </book>
                            <book>
                                <bktshort>Mark</bktshort>
                                <chapter>
                                <chtitle>Chapter 1</chtitle>
                                <v>The beginning of the good news about Jesus the Messiah,[a] the Son of God,</v>
                                </chapter>
                            </book>
                        </bookcoll>
                                ' 

SELECT  BookTitle = Chapter.value('../../bktshort[1]', 'varchar(200)')
      , Chapter = REPLACE(Chapter.value('../chtitle[1]', 'varchar(200)'), 'Chapter ', '')
      , RunningVerse = ROW_NUMBER() OVER ( PARTITION BY Chapter.value('../../bktshort[1]', 'varchar(200)') ORDER BY Chapter.value('../../bktshort[1]',
                                                                                                        'varchar(200)') )
      , Scripture = Chapter.value('.', 'varchar(max)')
FROM    @xml.nodes('/bookcoll/book/chapter/v') T ( chapter ) 

答案 1 :(得分:0)

我的第一个解决方案是

SELECT 
    BQ.BookName
,   BQ.BookNumber
,   CQ.ChapterTitle
,   CQ.ChapterNumber
,   VQ.VerseText
,   VQ.VerseNumber
,   ROW_NUMBER() OVER (ORDER BY BQ.BookNumber, CQ.ChapterNumber,VQ.VerseNumber)
FROM
    (SELECT Books.value('bktshort[1]', 'varchar(200)') as BookName,
        p.number as BookNumber
    FROM master..spt_values p
    CROSS APPLY
        @xml.nodes('/bookcoll/book[position()=sql:column("number")]') B(Books)
    WHERE p.type='p'
    ) BQ
INNER JOIN
    (SELECT C.Chapter.value('../bktshort[1]', 'varchar(200)') as BookName,
    C.Chapter.value('chtitle[1]', 'varchar(200)') as ChapterTitle,
        p.number as ChapterNumber
    FROM master..spt_values p
    CROSS APPLY
        @xml.nodes('/bookcoll/book/chapter[position()=sql:column("number")]') C(Chapter)
    WHERE p.type='p'
    ) CQ
    on BQ.BookName = CQ.BookName
INNER JOIN
    (SELECT V.Verses.value('../../bktshort[1]', 'varchar(200)') as BookName,
    V.Verses.value('../chtitle[1]', 'varchar(200)') as ChapterTitle,
    V.Verses.value('.', 'varchar(max)') as VerseText,
        p.number as VerseNumber
    FROM master..spt_values p
    CROSS APPLY
        @xml.nodes('/bookcoll/book/chapter/v[position()=sql:column("number")]') V(Verses)
    WHERE p.type='p'
    ) VQ
    on CQ.BookName = VQ.BookName
    and CQ.ChapterTitle = VQ.ChapterTitle

但这需要两分钟才能运行,所以我仍在接受建议