如何在祖先元素父级中获取祖先元素的位置/索引

问题描述

我的 xml 看起来像这样:

<items>
    <item>
      <itemproperty>true</itemproperty>
      <details>
        <details>
          <ID Type="z" Value="1"/>
          <ID Type="w" Value="2"/>
        </details>
      </Locations>
    </item>
    <item>
      <itemproperty>true</itemproperty>
      <details>
        <details>
          <ID Type="a" Value="3"/>
          <ID Type="b" Value="4"/>
        </details>
      </Locations>
    </item>
</items>

我想产生这样的输出:

ItemIndex    DetailIDType     DetailIDValue
1            z                1
1            w                2
2            a                3
2            b                4

我从 /items/item/details/detail/ID 节点查询并尝试找出祖先项元素的位置/索引。我可以获得 item 元素的总数,但我很难找到 item 元素的位置。在所有情况下,它都没有返回正确的索引/位置值:

SELECT DISTINCT
    [TestGetItemElementName] = IDs.id.value('fn:local-name(./../../..)','varchar(50)'),[TestGetItemElementCount] = IDs.id.value('count(/items/item)','int'),[ItemIndexTest1] = IDs.id.value('for $i in ./../../.. return count(/items/item/*[. << $i]) + 1',[ItemIndexTest2] = IDs.id.value('for $i in . return count(../*[. << $i]) + 1',[DetailIDType] = convert(VARCHAR(256),IDs.id.query('data(./@Type)')),[DetailIDValue] = convert(VARCHAR(256),IDs.id.query('data(./@Value)'))
FROM 
    @x.nodes('/Recipients/Recipient/Locations/Location/ID') AS IDs(id)

解决方法

尽量避免在 XPath 查询中使用父轴(..parent::node()),因为它会严重影响性能。

您可以通过使用 DENSE_RANK() 来提供 item 节点的自动编号,并使用如下代码实现您要查找的内容...

declare @x xml = N'<items>
    <item>
      <itemproperty>true</itemproperty>
      <Locations>
        <details>
          <ID Type="z" Value="1"/>
          <ID Type="w" Value="2"/>
        </details>
      </Locations>
    </item>
    <item>
      <itemproperty>true</itemproperty>
      <Locations>
        <details>
          <ID Type="a" Value="3"/>
          <ID Type="b" Value="4"/>
        </details>
      </Locations>
    </item>
</items>';

select
  dense_rank() over (partition by items order by item) as ItemIndex,details.value('@Type',N'nvarchar(256)') as DetailIDType,details.value('@Value',N'nvarchar(256)') as DetailIDValue
from @x.nodes('//items') nodes1(items)
cross apply items.nodes('item') nodes2(item)
cross apply item.nodes('Locations/details/ID') nodes3(details);

产生的结果:

ItemIndex DetailIDType DetailIDValue
1 z 1
1 w 2
2 3
2 b 4
,

我看到您尝试使用 节点比较 运算符来获取 ItemIndex 列值。以下是正确操作的方法。

SQL

>readelf -S app

There are 27 section headers,starting at offset 0x270:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000401000  00001000
       000000000223c47d  0000000000000000  AX       0     0     16
  [ 2] .plt              PROGBITS         000000000263d480  0223d480
       0000000000000290  0000000000000010  AX       0     0     16
  [ 3] .rodata           PROGBITS         000000000263e000  0223e000
       0000000000cd4919  0000000000000000   A       0     0     32
  [ 4] .rela             RELA             0000000003312920  02f12920
       0000000000000018  0000000000000018   A      11     0     8
  [ 5] .rela.plt         RELA             0000000003312938  02f12938
       00000000000003c0  0000000000000018   A      11     2     8
  [ 6] .gnu.version_r    VERNEED          0000000003312d00  02f12d00
       0000000000000050  0000000000000000   A      10     2     8
  [ 7] .gnu.version      VERSYM           0000000003312d60  02f12d60
       000000000000005a  0000000000000002   A      11     0     2
  [ 8] .hash             HASH             0000000003312dc0  02f12dc0
       00000000000000d8  0000000000000004   A      11     0     8
  [ 9] .shstrtab         STRTAB           0000000000000000  02f12ea0
       0000000000000111  0000000000000000           0     0     1
  [10] .dynstr           STRTAB           0000000003312fc0  02f12fc0
       0000000000000268  0000000000000000   A       0     0     1
  [11] .dynsym           DYNSYM           0000000003313240  02f13240
       0000000000000438  0000000000000018   A      10     1     8
  [12] .typelink         PROGBITS         0000000003313680  02f13680
       000000000001064c  0000000000000000   A       0     0     32
  [13] .itablink         PROGBITS         0000000003323cd0  02f23cd0
       0000000000006a60  0000000000000000   A       0     0     8
  [14] .gosymtab         PROGBITS         000000000332a730  02f2a730
       0000000000000000  0000000000000000   A       0     0     1
  [15] .gopclntab        PROGBITS         000000000332a740  02f2a740
       000000000113d450  0000000000000000   A       0     0     32
  [16] .go.buildinfo     PROGBITS         0000000004468000  04068000
       0000000000000020  0000000000000000  WA       0     0     16
  [17] .dynamic          DYNAMIC          0000000004468020  04068020
       0000000000000130  0000000000000010  WA      10     0     8
  [18] .got.plt          PROGBITS         0000000004468160  04068160
       0000000000000158  0000000000000008  WA       0     0     8
  [19] .got              PROGBITS         00000000044682b8  040682b8
       0000000000000008  0000000000000008  WA       0     0     8
  [20] .noptrdata        PROGBITS         00000000044682c0  040682c0
       00000000000885c0  0000000000000000  WA       0     0     32
  [21] .data             PROGBITS         00000000044f0880  040f0880
       000000000001f630  0000000000000000  WA       0     0     32
  [22] .bss              NOBITS           000000000450fec0  0410fec0
       000000000003ba90  0000000000000000  WA       0     0     32
  [23] .noptrbss         NOBITS           000000000454b960  0414b960
       0000000000004708  0000000000000000  WA       0     0     32
  [24] .tbss             NOBITS           0000000000000000  00000000
       0000000000000008  0000000000000000 WAT       0     0     8
  [25] .interp           PROGBITS         0000000000400fe4  00000fe4
       000000000000001c  0000000000000000   A       0     0     1
  [26] .note.go.buildid  NOTE             0000000000400f80  00000f80
       0000000000000064  0000000000000000   A       0     0     4
Key to Flags:
  W (write),A (alloc),X (execute),M (merge),S (strings),I (info),L (link order),O (extra OS processing required),G (group),T (TLS),C (compressed),x (unknown),o (OS specific),E (exclude),l (large),p (processor specific)

输出

DECLARE @x XML = 
N'<items>
    <item>
      <itemproperty>true</itemproperty>
      <Locations>
        <details>
          <ID Type="z" Value="1"/>
          <ID Type="w" Value="2"/>
        </details>
      </Locations>
    </item>
    <item>
      <itemproperty>true</itemproperty>
      <Locations>
        <details>
          <ID Type="a" Value="3"/>
          <ID Type="b" Value="4"/>
        </details>
      </Locations>
    </item>
</items>';

SELECT c.value('for $i in . return count(/items/item[. << $i])','INT') AS ItemIndex,c.value('@Type','VARCHAR(20)') as DetailIDType,c.value('@Value','INT') as DetailIDValue
FROM @x.nodes('/items/item/Locations/details/ID') AS t(c);

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...