0

我正在拼命地想办法解决这个问题,但没有运气。我正在尝试在 Postgres 中解析这些 XML 数据:

<map>
  <entry>
    <string>id</string>
    <string>555</string>
  </entry>
  <entry>
    <string>label</string>
    <string>Need This Value</string>
  </entry>
  <entry>
    <string>key</string>
    <string>748</string>
  </entry>
</map>

我试图string<string>label</string>. 请注意,我正在使用的 Postgres 版本没有安装 XML (libxml) 函数。

我尝试了许多变体:

substring(xmlStringData from E'<string>label</string>\\n<string>(.*?)</string>')

但没有运气。

4

3 回答 3

2

xpath()将是这里的正确工具。因为,你知道...

在遇到不幸的情况时,这可以解决问题:

WITH t(x) AS (SELECT '<map>
  <entry>
    <string>id</string>
    <string>555</string>
  </entry>
  <entry>
    <string>label</string>
    <string>Need This Value</string>
  </entry>
  <entry>
    <string>key</string>
    <string>748</string>
  </entry>
</map>'::text
)
SELECT substring(x, '<string>label</string>[\s]*?<string>(.*?)</string>')
FROM  t

回报:

substring
---------------
Need This Value

正则表达式解释:

<string>label</string>.. 找到位置
[\s].. 空格(包括\nand \r
*?.. 这样做“非贪婪”,所以忽略空格直到 ...
<string>.. 下一个字符串元素
(.*?).. 捕获括号,任何字符,非贪婪
</string>.. up到结束标签的下一次出现

这是可靠的,除非您使用非常规的 XML 格式 - 这就是为什么您应该使用 XML 解析器开始...

于 2014-07-30T16:44:41.903 回答
0

所以我似乎明白了。我只需要考虑换行符后的空格。解决方案是:

substring(event_data from E'<string>label</string>\\n\\s*?<string>(.*?)</string>')
于 2014-07-30T16:14:27.193 回答
0

如果您的<entry>列表不可变。您可以使用以下正则表达式并访问第 4 场比赛中的捕获组来获取内容。

<string>(.*?)<\/string>

工作演示

另一方面,如果您想在第一场比赛中访问,您可以使用以下正则表达式:

<string>id<\/string>|<string>\d+<\/string>|<string>label<\/string>|<string>(.*?)<\/string>

工作演示

于 2014-07-30T16:14:42.013 回答