Xml unest(xpath())不';无法正确识别空值

Xml unest(xpath())不';无法正确识别空值,xml,postgresql,plpgsql,Xml,Postgresql,Plpgsql,PostgreSQL 9.6版,使用xml2扩展。我试图从XML中提取行并将它们插入到postgreSQL表中。下面是一个简短的示例: ROLLBACK; BEGIN; DO $$ DECLARE v_xml xml; v_record RECORD; BEGIN v_xml := '<?xml version="1.0" encoding="UTF-16"?> <root> <table> <row>&l

PostgreSQL 9.6版,使用xml2扩展。我试图从XML中提取行并将它们插入到postgreSQL表中。下面是一个简短的示例:

ROLLBACK;
BEGIN;
DO $$
DECLARE 
    v_xml xml;
    v_record RECORD;
BEGIN
v_xml := '<?xml version="1.0" encoding="UTF-16"?>
<root>
    <table>
        <row><a>1</a><b>2</b><c>3</c></row>
        <row><a></a><b>5</b><c>6</c></row>
        <row><a>7</a><b>8</b><c>9</c></row> 
    </table>
</root>'::text;

CREATE TEMPORARY TABLE temptable( col_a text, col_b text, col_c text ) ON COMMIT DROP;
INSERT INTO temptable VALUES
(
    unnest(xpath('/root/table/row/a/text()', v_xml))::text,
    unnest(xpath('/root/table/row/b/text()', v_xml))::text,
    unnest(xpath('/root/table/row/c/text()', v_xml))::text
);

-- display table contents
FOR v_record IN SELECT * FROM temptable LOOP
    RAISE NOTICE 'col_a: % col_b: % col_c: %', v_record.col_a, v_record.col_b, v_record.col_c;
END LOOP;
END $$;
但是,对于缺少的值或空值,unnest()无法正确识别它们,并使用列数组中的下一个值(应该为下一行读取)

为了演示,请按如下方式修改XML(即,将前面的4和9值设为null,或完全删除元素):

一些调试语句揭示了三个未列出的列数组是{1,7}、{2,5,8}和{3,6}。插入给定行时,没有占位符空值可用作列值


是否有另一种方法来实现untesting,以正确解释null或缺少的节点值?

这不是
unest
的问题,而是
xpath
的问题,它似乎没有在返回的数组中包含null值

选择XPATH('/root/table/row/a/text(),'13'::XML)
返回
{1,3}

解决这个问题的一种方法是首先对元素执行
xpath
,然后访问值:

SELECT (XPATH('/a/text()', u))[1]
FROM UNNEST(XPATH('/root/table/row/a', '<root><table><row><a>1</a><a></a><a>3</a></row></table></root>'::XML)) u
<table>
    <row><a>1</a><b>2</b><c>3</c></row>
    <row><a></a><b>5</b><c>6</c></row>
    <row><a>7</a><b>8</b><c></c></row>  
</table>
NOTICE:  col_a: 1 col_b: 2 col_c: 3
NOTICE:  col_a: 7 col_b: 5 col_c: 6
NOTICE:  col_a: 1 col_b: 8 col_c: 3
NOTICE:  col_a: 7 col_b: 2 col_c: 6
NOTICE:  col_a: 1 col_b: 5 col_c: 3
NOTICE:  col_a: 7 col_b: 8 col_c: 6
SELECT (XPATH('/a/text()', u))[1]
FROM UNNEST(XPATH('/root/table/row/a', '<root><table><row><a>1</a><a></a><a>3</a></row></table></root>'::XML)) u
1

3