在Postgres中将JSONB转换为XML

在Postgres中将JSONB转换为XML,xml,postgresql,postgrest,Xml,Postgresql,Postgrest,我有一张桌子 创建表文档( id串行主键, author\u id整数非空外键引用(author.id) 内容XML不为空, 已创建时区非空的时间戳默认当前\u时间戳 ) 我想将数据库从使用XML转换为使用JSONB来存储数据。我想分三个阶段进行: 创建一些视图/函数,将现有数据动态转换为JSONB;通过Postgrest API浮出水面 将现有系统从使用XML迁移到使用JSONB,并使用旧的API代码 将列从XML永久转换为JSONB 这允许软件在重构部分API以使用新API(JSONB)的

我有一张桌子

创建表文档(
id串行主键,
author\u id整数非空外键引用(author.id)
内容XML不为空,
已创建时区非空的时间戳默认当前\u时间戳
)
我想将数据库从使用XML转换为使用JSONB来存储数据。我想分三个阶段进行:

  • 创建一些视图/函数,将现有数据动态转换为JSONB;通过Postgrest API浮出水面
  • 将现有系统从使用XML迁移到使用JSONB,并使用旧的API代码
  • 将列从XML永久转换为JSONB
  • 这允许软件在重构部分API以使用新API(JSONB)的同时使用旧API(使用XML数据)。一旦重构完成,我就可以结束过去喜欢XML的日子了

    我找到了将数据从XML转换为JSONB的答案:

    经过一些修改,我可以使它(非常)符合我现有的代码。简而言之,我可以将其转换为:

    
    世界
    船长
    
    对此

    {
        "xml": {
            "@tag": "xml",
            "this": {
                "@tag": "this",
                "@value": "captain",
                "@attributes": {
                    "is": "your"
                }
            },
            "hello": {
                "@tag": "hello",
                "@value": "world",
                "@attributes": {}
            },
            "@value": null,
            "@attributes": {}
        }
    }
    
    编辑:由于@404的反馈,上面的内容已稍微修改

    但我需要某种方法允许重构代码将JSONB发送到新的(Postgrest)API,然后将数据转换为XML,以便非重构代码仍然可以使用它

    我已经看过了,但我正在努力实现它,以便能够动态地将JSONB转换回XML表单(如果有点凌乱,也无所谓,只要我以后可以返回JSON表单)。看起来我能做到,好吗

    SELECT xmlelement(name hello, null, 'world')
    
    但是当我试着这么做的时候

    SELECT xmlelement(name key, null, value)
    FROM jsonb_each('{
            "this": {
                "@value": "captain",
                "@attributes": {
                    "is": "your"
                }
            },
            "hello": {
                "@value": "world",
                "@attributes": {}
            },
            "@value": null,
            "@attributes": {}
        }'
    )
    
    正如您所期望的,您可以得到如下XML输出

    {@value:“captain”,“attributes:{”is:“your”}

    。。。其中XML元素称为“key”,而不是键列的值(在本例中为“this”)

    我在使用
    xmldattributes
    函数时也遇到类似的问题-我无法为属性指定来自数据库查询的名称

    是否有一种动态设置XML元素标记名和属性名的方法?


    更新:阅读下面的评论;无论如何,上述方法可能是错误的。我留下了一个问题,以防有办法,因为它可能会帮助某人在未来。。。但我的收获是,我需要首先重新思考数据结构。

    一些想法。我不关心xml转换创建的JSON结构。我的结构如下:
    {“name”:“xml”,“value”:null,“attributes”:null,“children”:[{“name”:“this”,“value”:“captain”,“attributes”:[{“name”:“is”,“value”:“your”}]},{“name:”hello“,…}]}
    。更改的键名并不重要,更重要的是(1)不使用值作为键名,因为这样JSON模式可以在各个条目之间保持一致,允许您在不知道项目名称的情况下选择项目名称;(b)使用特定属性(续…)…来保存子元素,因为这样可以更容易地创建一个函数,它可以递归地为
    当前项目->子元素-/code>中的每个元素调用自己,当它遍历可能有多少嵌套元素时,为每个元素返回相同的结构。因此,基本上我认为您需要一个更好的JSON结构,而这反过来将l允许您更轻松地执行相反的转换。由于我无法编辑注释,因此子对象(
    “name”):“this”
    )也应该具有
    children
    属性(或者如果没有子元素,则可以省略该属性),以便xml元素的每个表示都是相同的结构,无论其处于何种级别。”我可能需要遍历整个数组,看看是否有“hello”元素——好吧,我想我的观点是,你永远不会寻找特定的元素,更多的是关于翻译友好的结构“json结构,那么我认为更重要的是改变结构,因为现在它超级绑定到xml(例如“属性”)。我会说:忘记翻译和xml,先弄清楚你想要它看起来像什么,然后看看如何在两者之间进行翻译(可能在这里发布一个问题)。只是补充一下,我不久前也做了类似的事情:我们在postgres中存储了这个复杂的xml结构,然后想将其更改为json。但我们需要两个版本有一段时间了。因此,我们定义了我们想要的json结构,然后使用视图公开xml版本和json版本(在视图中动态转换,并通过触发器在写入时从json转换为xml)。我想这和你在这里所做的很相似。