从oracle中的xmltype属性获取名称和值

时间:2016-07-06 12:52:46

标签: sql xml oracle xpath plsql

描述

您好,我在Oracle中从XMLType值中提取属性名称和值时遇到问题。 基本上,我有一张表,让我们说TableA,它有一个XMLType列,让我们称之为TableA_configTableA_config中的值具有以下结构: <TableAConfig someAttribute1="value1" someAttribute2="value2" someAttribute3="value3" />。属性的数量及其名称可能会有所不同,并且事先不知道。 我需要做的是(对于每一行)创建名为TableAConfigList的新XMLElement,其中包含名为TableAConfig的XMLElements,每个属性都有两个属性:namevalue。现在,TableAConfig个节点的数量必须等于TableA_config列中的属性数量,每个节点都包含name属性中相应属性的名称及其value属性中的值。

实施例

自:

<TableAConfig someAttribute1="value1" someAttribute2="value2" someAttribute3="value3" />

我应该得到:

<TableAConfigList>
    <TableAConfig name="someAttribute1" value="value1"/>
    <TableAConfig name="someAttribute2" value="value2"/>
    <TableAConfig name="someAttribute3" value="value3"/>
</TableAConfigList>

我尝试了什么

我想出了从XMLTable列值创建TableA_config的想法,并在其中创建了两列,我可以稍后选择。它看起来像这样(它是一个更大的查询的片段):

SELECT XMLElement("TableAConfigList",
    (SELECT
        XMLAgg(
           XMLElement("TableAConfig",
                XMLAttributes(
                    tmp."attr_name" as "name",
                    tmp."attr_text" as "value"
                )
            )
        ) from XMLTable('/TableAConfig/@*'
            passing TableA.TableA_config
            columns
               "attr_name" varchar(30) path 'name()',
               "attr_text" varchar(30) path 'text()'
        ) tmp
    )
) from dual

但现在我明白了:

<TableAConfigList>
    <TableAConfig name="someAttribute1"></TableAConfig>
    <TableAConfig name="someAttribute2"></TableAConfig>
    <TableAConfig name="someAttribute3"></TableAConfig>
</TableAConfigList>

没有value。但是,如果我从name移除XMLAttributes,则会显示。从:

SELECT XMLElement("TableAConfigList",
    (SELECT
        XMLAgg(
           XMLElement("TableAConfig",
                XMLAttributes(
                    tmp."attr_text" as "value"
                )
            )
        ) from XMLTable('/TableAConfig/@*'
            passing TableA.TableA_config
            columns
               "attr_name" varchar(30) path 'name()',
               "attr_text" varchar(30) path 'text()'
        ) tmp
    )
) from dual

我明白了:

<TableAConfigList>
    <TableAConfig value="value1"></TableAConfig>
    <TableAConfig value="value2"></TableAConfig>
    <TableAConfig value="value3"></TableAConfig>
</TableAConfigList>

我认为可能由于某种原因,只能通过这种方式创建一个属性,但如果我通过硬编码添加新属性,它会显示在结果中,如下所示:

SELECT XMLElement("TableAConfigList",
    (SELECT
        XMLAgg(
           XMLElement("TableAConfig",
                XMLAttributes(
                    tmp."attr_text" as "value",
                    'testValue' as "testAttribute"
                )
            )
        ) from XMLTable('/TableAConfig/@*'
            passing TableA.TableA_config
            columns
               "attr_name" varchar(30) path 'name()',
               "attr_text" varchar(30) path 'text()'
        ) tmp
    )
) from dual

结果:

<TableAConfigList>
    <TableAConfig value="value1" testAttribute="testValue"></TableAConfig>
    <TableAConfig value="value2" testAttribute="testValue"></TableAConfig>
    <TableAConfig value="value3" testAttribute="testValue"></TableAConfig>
</TableAConfigList>

XMLAttributes两列和硬编码列放入nametestAttribute,但没有value

有人能告诉我是因为我错过了一些非常明显的东西,这是一个错误还是我完全错了。我是Oracle和PL / SQL的新手,非常感谢您的帮助。谢谢!

2 个答案:

答案 0 :(得分:1)

你的第一次尝试几乎就在那里。在评估XPath时,当您使用/TableAConfig/@*进入属性列表时,您不需要text()来获取其中的属性值。您已经处于属性级别,因此仅使用&#34; dot&#34; <{1}}对于当前节点就足够了。

所以尝试这样的事情 -

.

与您第一次尝试的唯一区别是SELECT XMLElement("TableAConfigList", (SELECT XMLAgg( XMLElement("TableAConfig", XMLAttributes( tmp."attr_name" as "name", tmp."attr_text" as "value" ) ) ) from XMLTable('/TableAConfig/@*' passing TableA.TableA_config columns "attr_name" varchar(30) path 'name()', "attr_text" varchar(30) path '.' ) tmp ) ) from dual 属性的xpath。

答案 1 :(得分:0)

您也可以使用XMLTRANSFORM

select xmltransform(
       xmltype('<TableAConfig someAttribute1="value1" someAttribute2="value2" someAttribute3="value3" />'),
       xmltype('<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:for-each select="TableAConfig">
<TableAConfigList>
            <xsl:for-each select="@*">
                <xsl:element name="TableAConfig" >
                    <xsl:attribute name="name">
                        <xsl:value-of select="name()"/>
                    </xsl:attribute>
                    <xsl:attribute name="value">
                        <xsl:value-of select="."/>
                    </xsl:attribute>
                </xsl:element>
            </xsl:for-each>
</TableAConfigList>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>'))
from dual