如何在 SQL 中使用 xml 命名空间通配符(表中具有不同命名空间 url 的多个 xml 文件)

jmhrides

我有一个 SQL 文件表,其中存储了多个 xml 文件以用于 SQL。xml 文件的内容不在我的控制范围内。我只需要将它们用作我的表的输入。所有 xml 文件都具有相同的结构/设置。唯一的问题是我刚刚意识到其中一些 xml 文件具有不同的命名空间 url(因此在我的表中返回 NULL)。

我正在使用 xml 文件创建一个表,其中来自 xml 的键作为列返回,属性作为行中的值返回。每个 xml 都作为行返回。

所以我现在遇到的问题是,对于所有具有(稍微)不同命名空间的 xml,整行都返回 NULL。

使用的命名空间是:http : //schemas.kvk.nl/xb/query/service/2016/1/0/0http://schemas.kvk.nl/xb/query/service/2017/1/0 /0

我使用的查询:

WITH XMLNAMESPACES('http://schemas.kvk.nl/xb/query/service/2016/1/0/0' AS ns2) -- Pull namespaces for NS2
SELECT p.*
FROM
(
    SELECT [name]
    ,x.l.value('(ns2:opendataField[@key="SbiBusinessCode"]/@value)[1]','varchar(max)') AS SBI
    ,x.l.value('(ns2:opendataField[@key="FinancialYear"]/@value)[1]','varchar(max)') AS FY
    from dbo.XBRLft t -- filestream table
    CROSS APPLY(SELECT CAST(t.[file_stream] AS XML)) A(xbrl) -- convert filestream into xml.
    CROSS APPLY xbrl.nodes('/opendata') x(l) 
    where x.l.exist('./*/@key')=1 
    ) p  

这将返回仅包含第一个命名空间(因为在查询中使用)的值的表,但基于具有第二个命名空间的 xml 的每一行都返回 null。

所以我尝试使用通配符而不是命名空间,但这只会返回错误。

SELECT p.*
FROM
(
    SELECT [name]
    -- Putting all key's as columns and showing the attribute value in row.
    ,x.l.value('(//*:ns2:opendataField[@key="FinancialYear"]/@value)[1]','varchar(max)') AS FY
    from dbo.XBRLft t -- filestream table
    CROSS APPLY(SELECT CAST(t.[file_stream] AS XML)) A(xbrl) -- 
    CROSS APPLY xbrl.nodes('//*:opendata') x(l) -- 
    where x.l.exist('./*/@key')=1 -- 
    ) p

查询中有更多的键,但在此示例中将它们排除在外。

知道如何通过应用 2 个命名空间 url 或修复通配符来完成这项工作吗?

更新

这是 2 个示例(每个 XML 的 1 个具有不同的命名空间)。我不确定是否可以使用 COALESCE,因为两个 XML 版本都在整个 xml 中使用 ns2(并且我需要在查询中添加整个路径以获取不同的键/值,因为 xml 是分层的)。

XML 1:

<opendata xmlns:ns2="http://schemas.kvk.nl/xb/query/service/2016/1/0/0">
  <ns2:opendataField key="DocumentAdoptionDate" value="2017-08-27" />
  <ns2:opendataField key="FinancialYear" value="2016" />
  <ns2:opendataField key="BalanceSheet">
    <ns2:opendataField key="BalanceSheetBeforeAfterAppropriationResultsTitle">
      <ns2:opendataField key="BalanceSheetBeforeAfterAppropriationResults" value="Na" />
    </ns2:opendataField>
    <ns2:opendataField key="BalanceSheetTitle">
      <ns2:opendataField key="Assets" value="548985">
        <ns2:opendataField key="AssetsNoncurrent" value="447571">
          <ns2:opendataField key="PropertyPlantEquipment" value="208215" />
          <ns2:opendataField key="FinancialAssets" value="239355" />
        </ns2:opendataField>
        <ns2:opendataField key="AssetsCurrent" value="101414">
          <ns2:opendataField key="Receivables" value="68895" />
          <ns2:opendataField key="CashAndCashEquivalents" value="32519" />
        </ns2:opendataField>
      </ns2:opendataField>
etc etc

XML2

<opendata xmlns:ns2="http://schemas.kvk.nl/xb/query/service/2017/1/0/0">
  <ns2:opendataField key="DocumentAdoptionDate" value="2019-03-11" />
  <ns2:opendataField key="FinancialYear" value="2017" />
  <ns2:opendataField key="BalanceSheet">
    <ns2:opendataField key="BalanceSheetBeforeAfterAppropriationResultsTitle">
      <ns2:opendataField key="BalanceSheetBeforeAfterAppropriationResults" value="Na" />
    </ns2:opendataField>
    <ns2:opendataField key="BalanceSheetTitle">
      <ns2:opendataField key="Assets" value="184535">
        <ns2:opendataField key="AssetsCurrent" value="184535">
          <ns2:opendataField key="AssetsCurrentOther" value="184535" />
        </ns2:opendataField>
      </ns2:opendataField>
etc etc

因此,要获取我需要查询的键和值,如下所示:

 SELECT [name]
    -- Putting all key's as columns and showing the attribute value in row.
    ,x.l.value('(ns2:opendataField[@key="SbiBusinessCode"]/@value)[1]','varchar(max)') AS SBI
    ,x.l.value('(ns2:opendataField[@key="FinancialYear"]/@value)[1]','varchar(max)') AS FY
    ,x.l.value('(ns2:opendataField/ns2:opendataField/ns2:opendataField[@key="Assets"]/@value)[1]','varchar(max)') AS Assets
    ,x.l.value('(ns2:opendataField/ns2:opendataField/ns2:opendataField/ns2:opendataField[@key="AssetsNoncurrent"]/@value)[1]','varchar(max)') AS AssetsNoncurrent
    ,x.l.value('(ns2:opendataField/ns2:opendataField/ns2:opendataField/ns2:opendataField/ns2:opendataField[@key="IntangibleAssets"]/@value)[1]','varchar(max)') AS IntangibleAssets
    ,x.l.value('(ns2:opendataField/ns2:opendataField/ns2:opendataField/ns2:opendataField/ns2:opendataField[@key="PropertyPlantEquipment"]/@value)[1]','varchar(max)') AS PropertyPlantEquipment

我不确定如何在此处应用您的 COALESCE 示例,因为这两种 XML 类型都包含 ns2,我需要整个路径。

再次感谢!

修吾

需要命名空间以避免相同名称之间的歧义。从这个角度来看,使用通配符可能非常危险,并可能导致意想不到的结果......

试试这个:

带有一些测试数据的虚拟表

DECLARE @tbl TABLE(id INT IDENTITY, YourXml XML);
INSERT INTO @tbl VALUES
('<root xmlns="blah1">
 <test>Test in 1</test>
 </root>'),
('<root xmlns="blah2">
 <test>Test in 2</test>
 </root>');

-- 这是你的问题:我们定义了默认命名空间,它仅适用于情况 1:

WITH XMLNAMESPACES(DEFAULT 'blah1')
SELECT t.id
      ,t.YourXml.value('(/root/test/text())[1]','nvarchar(100)') AS ContentOfTest
FROM @tbl t;

--但是我们可以使用两个带前缀的命名空间并使用 COALESCE 返回一个返回值的命名空间:

WITH XMLNAMESPACES('blah1' AS ns1
                  ,'blah2' AS ns2)
SELECT t.id
      ,COALESCE(
       t.YourXml.value('(/ns1:root/ns1:test/text())[1]','nvarchar(100)') 
      ,t.YourXml.value('(/ns2:root/ns2:test/text())[1]','nvarchar(100)') 
       ) AS ContentOfTest
FROM @tbl t

--这是使用通配符的方法,如果您可以确定,这不会导致歧义:

SELECT t.id
      ,t.YourXml.value('(/*:root/*:test/text())[1]','nvarchar(100)') AS ContentOfTest
FROM @tbl t

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在SQL Server 2008中使用xmlnamespaces读取具有命名空间的XML文件

来自分类Dev

反序列化具有不同命名空间的 xml 文件

来自分类Dev

如何使用带有XML文件中命名空间的XSLT样式表展平分层XML文件

来自分类Dev

使用 C# 解析具有多个命名空间的 Xml

来自分类Dev

如何在SQL Server中使用命名空间解析XML

来自分类Dev

如何在XElement中使用特殊的“ xml”命名空间前缀

来自分类Dev

如何在Oracle中使用命名空间查询XML?

来自分类Dev

如何在XElement中使用特殊的“ xml”命名空间前缀

来自分类Dev

如何在Oracle中使用命名空间查询XML?

来自分类Dev

如何在SQL查询中解析多个名称空间xml

来自分类Dev

如何在Android中使用多个xml“样式表”?

来自分类Dev

如何从xml中检索元素值并从SQL Server获得多个命名空间?

来自分类Dev

如何从xml中检索元素值并从SQL Server获得多个命名空间?

来自分类Dev

使用 Python 3 ElementTree 的 XML 文档中的多个命名空间

来自分类Dev

如何使用 python 从soap响应中的多个命名空间获取数据:xml.etree.ElementTree

来自分类Dev

如何从具有命名空间的XML中获取节点

来自分类Dev

如何使用javascript读取具有多个节点的xml文件

来自分类Dev

使用 Oracle SQL 读取 XML 命名空间

来自分类Dev

如何在一个xsl文档中使用两个(或多个)xml文件?

来自分类Dev

如何在SQL Server中添加或更改Xml命名空间/名称表达式中不能使用“ xmlns”

来自分类Dev

如何在Oracle SQL中使用XMLQuery(XQuery)插入多个xml节点?

来自分类Dev

使用命名空间在SQL Server中查询XML

来自分类Dev

如何在 XML C# 中获得多个命名空间?

来自分类Dev

如何在 Java 中读取多个 XML 文件?

来自分类Dev

在python 2.7 lxml中使用命名空间访问xml文件中的值

来自分类Dev

如何使用php加载多个xml文件

来自分类Dev

如何使用在多个文件(.xml)中具有共享引用的JAXB解组文件

来自分类Dev

如何在Spring 3.1中使用通配符加载xml资源文件

来自分类Dev

如何使用XMLStreamReader读取xml中的命名空间?

Related 相关文章

  1. 1

    在SQL Server 2008中使用xmlnamespaces读取具有命名空间的XML文件

  2. 2

    反序列化具有不同命名空间的 xml 文件

  3. 3

    如何使用带有XML文件中命名空间的XSLT样式表展平分层XML文件

  4. 4

    使用 C# 解析具有多个命名空间的 Xml

  5. 5

    如何在SQL Server中使用命名空间解析XML

  6. 6

    如何在XElement中使用特殊的“ xml”命名空间前缀

  7. 7

    如何在Oracle中使用命名空间查询XML?

  8. 8

    如何在XElement中使用特殊的“ xml”命名空间前缀

  9. 9

    如何在Oracle中使用命名空间查询XML?

  10. 10

    如何在SQL查询中解析多个名称空间xml

  11. 11

    如何在Android中使用多个xml“样式表”?

  12. 12

    如何从xml中检索元素值并从SQL Server获得多个命名空间?

  13. 13

    如何从xml中检索元素值并从SQL Server获得多个命名空间?

  14. 14

    使用 Python 3 ElementTree 的 XML 文档中的多个命名空间

  15. 15

    如何使用 python 从soap响应中的多个命名空间获取数据:xml.etree.ElementTree

  16. 16

    如何从具有命名空间的XML中获取节点

  17. 17

    如何使用javascript读取具有多个节点的xml文件

  18. 18

    使用 Oracle SQL 读取 XML 命名空间

  19. 19

    如何在一个xsl文档中使用两个(或多个)xml文件?

  20. 20

    如何在SQL Server中添加或更改Xml命名空间/名称表达式中不能使用“ xmlns”

  21. 21

    如何在Oracle SQL中使用XMLQuery(XQuery)插入多个xml节点?

  22. 22

    使用命名空间在SQL Server中查询XML

  23. 23

    如何在 XML C# 中获得多个命名空间?

  24. 24

    如何在 Java 中读取多个 XML 文件?

  25. 25

    在python 2.7 lxml中使用命名空间访问xml文件中的值

  26. 26

    如何使用php加载多个xml文件

  27. 27

    如何使用在多个文件(.xml)中具有共享引用的JAXB解组文件

  28. 28

    如何在Spring 3.1中使用通配符加载xml资源文件

  29. 29

    如何使用XMLStreamReader读取xml中的命名空间?

热门标签

归档