简体   繁体   English

如何从 XMLTYPE 列中提取,相应的 label 用于来自相同 XML 的值/标签列表中的标签中的值

[英]How Extract from XMLTYPE column, corresponding label for value in a tag within a value/label list from same XML

I got a sql from an Oracle table with a XMLTYPE column.我从带有 XMLTYPE 列的 Oracle 表中得到一个 sql。 The Xml has a tag with a value '2' and in the same xml there is the list with value/label pairs like this: Xml 有一个值为“2”的标签,在同一个 xml 中有一个值/标签对列表,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<Root>
    <characteristics>
        <motor>
            <fuel>2</fuel>
        </motor>
    </characteristics>
    <ValuesList>
        <CarValues>
            <CarValue>
                <value>1</value>
                <label>Diesel</label>
            </CarValue>
            <CarValue>
                <value>2</value>
                <label>Unleaded petrol</label>
            </CarValue>
        </CarValues>
    </ValuesList>
</Root>

With extract() or extractValue() functions it's easy to get the value for tag with any of these staments a, b使用extract()extractValue()函数,可以很容易地使用这些语句 a、b 中的任何一个获取标签的值

SELECT extract(t.xmlColumn, '//fuel/text()').getStringVal() a,
       extractValue(t.xmlColumn, '//fuel') b
  FROM Table t

The problem is I want to get the label text for value '2' from Valueslist 'Unleaded petrol'问题是我想从 Valueslist 'Unleaded petrol' 中获取值 '2' 的 label 文本

I try to get that value with a XPATH expresion like this:我尝试使用 XPATH 表达式来获取该值,如下所示:

extractValue(t.xmlColumn, '//CarValue/label[../value=//fuel]')

The XPATH has been evaluated with Notepad XML Tools and it works, but there's no way to get any result. XPATH 已经用记事本 XML 工具进行了评估,可以使用,但是没有办法得到任何结果。 it's always null.它总是 null。

Any idea how to achive this?知道如何实现这一目标吗? I don't know how to use XMLTABLE or any other solution to this case.我不知道如何使用 XMLTABLE 或任何其他解决方案来解决这种情况。

You need to include the /text() part in your attempt:您需要在尝试中包含/text()部分:

SELECT
extract(t.xmlColumn,'//fuel/text()').getStringVal() a
,extractValue(t.xmlColumn,'//fuel') b
,extractValue(t.xmlColumn, '//CarValue/label[../value=//fuel/text()]') c
FROM your_table t
A一种 B C C
2 2个 2 2个 Unleaded petrol无铅汽油

In your version you're trying to match a label with a value of the node <fuel>2</fuel> , not the text within than node, 2 .在您的版本中,您试图将 label 与节点<fuel>2</fuel>的值匹配,而不是节点2中的文本。

Both extract() and extractValue() are deprecated, so you could use XMLQuery instead: extract()extractValue()都已弃用,因此您可以改用 XMLQuery:

SELECT
XMLQuery('//fuel/text()' passing xmlColumn returning content) a
,XMLQuery('//CarValue/label[../value=//fuel/text()]/text()' passing xmlColumn returning content) a
FROM your_table t
A一种 A一种
2 2个 Unleaded petrol无铅汽油

Or with XMLTable();或者用 XMLTable();

SELECT x.a, x.b
FROM your_table t
CROSS APPLY XMLTable(
  '/'
  passing t.xmlColumn
  columns a number path '//fuel',
    b varchar2(30) path '//CarValue/label[../value=//fuel/text()]'
) x
A一种 B
2 2个 Unleaded petrol无铅汽油

fiddle小提琴


If your version of Oracle isn't working with the node traversal using ../ then you could do it the hard way by getting the fuel value and all the id/label pairs with separate XMLTable calls, and then filtering those that match:如果您的 Oracle 版本无法使用../进行节点遍历,那么您可以通过使用单独的 XMLTable 调用获取燃料值和所有 id/label 对,然后过滤匹配的那些来实现这一点:

SELECT x1.fuel, x2.label
FROM your_table t
CROSS JOIN XMLTable(
  '//fuel'
  passing t.xmlColumn
  columns fuel number path '.'
) x1
JOIN XMLTable(
  '//CarValue'
  passing t.xmlColumn
  columns value number path 'value',
    label varchar2(30) path 'label'
) x2 ON x2.value = x1.fuel
FUEL燃料 LABEL LABEL
2 2个 Unleaded petrol无铅汽油

fiddle小提琴

All solutions Alex Poole gave are accepted solutions for the question case title where "a value/label list within same XML" is present. Alex Poole 给出的所有解决方案都是问题案例标题的可接受解决方案,其中存在“同一 XML 中的值/标签列表”。

Just for information, in case "a value/label list is not present in the same XML", solution is create an auxiliary XMLTable with a XMLTYPE field and the value/label list XML in it.仅供参考,以防“同一 XML 中不存在值/标签列表”,解决方案是创建一个辅助 XMLTable,其中包含 XMLTYPE 字段和值/标签列表 XML。

SELECT x1.fuel, x2.labelFROM your_table t
CROSS JOIN XMLTable(
  '//fuel'
  passing t.xmlColumn
  columns fuel number path '.'
) x1
LEFT JOIN XMLTable(
  '//CarValue'
  passing 
  (SELECT XMLTYPE('
    <ValuesList>
        <CarValues>
            <CarValue>
                <value>1</value>
                <label>Diesel</label>
            </CarValue>
            <CarValue>
                <value>2</value>
                <label>Unleaded petrol</label>
            </CarValue>
        </CarValues>
    </ValuesList>
  ') FROM dual)
  columns value number path 'value',
    label varchar2(30) path 'label'
) x2 ON x2.value = x1.fuel

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM