我想从给定的xml中获取用'/'分隔的节点名称,以便仅获取节点/标记名称,而不是从给定的xml中获取节点/标记值。
假设我在xml以下:
<ns:manageWorkItemRequest>
<ns:wiFocus>
<act:orderDate>2020-03-16T10:30:56.000Z</act:orderDate>
<act:orderItem>
<agr:instance>
<spec1:customerServiceIdentifier>ETHA15302121</spec1:customerServiceIdentifier>
<spec1:instanceCharacteristic>
<spec1:action>
<spec1:code>Modify</spec1:code>
</spec1:action>
<spec1:instanceIdentifier>
<spec1:value>OS014-AHEFV5T9</spec1:value>
</spec1:instanceIdentifier>
</agr:instance>
</act:orderItem>
<act:orderVersion>1</act:orderVersion>
</ns:wiFocus>
<ns:wiAction>Create</ns:wiAction>
<ns:wiVersion>1</ns:wiVersion>
</ns:manageWorkItemRequest>
我希望结果为:
ns:manageWorkItemRequest / ns:wiFocus / act:orderItem / agr:instance / spec1:customerServiceIdentifier / ETHA15302121
实际要求是,如果我在上述xml中得到此“ ETHA15302121”值,则应该显示路径,即xml中该值正好以'/'分隔的格式。
您的XML格式不正确(中间缺少结束标记,缺少名称空间声明。
添加完缺少的部分后,看起来像这样,您可以沿这条路线尝试一些操作(警告:这不会很快...):
您的XML
DECLARE @xml XML=
N'<root xmlns:ns="dummy1" xmlns:act="dummy2" xmlns:agr="dummy3" xmlns:spec1="dummy4">
<ns:manageWorkItemRequest>
<ns:wiFocus>
<act:orderDate>2020-03-16T10:30:56.000Z</act:orderDate>
<act:orderItem>
<agr:instance>
<spec1:customerServiceIdentifier>ETHA15302121</spec1:customerServiceIdentifier>
<spec1:instanceCharacteristic>
<spec1:action>
<spec1:code>Modify</spec1:code>
</spec1:action>
<spec1:instanceIdentifier>
<spec1:value>OS014-AHEFV5T9</spec1:value>
</spec1:instanceIdentifier>
</spec1:instanceCharacteristic>
</agr:instance>
</act:orderItem>
<act:orderVersion>1</act:orderVersion>
</ns:wiFocus>
<ns:wiAction>Create</ns:wiAction>
<ns:wiVersion>1</ns:wiVersion>
</ns:manageWorkItemRequest>
</root>';
-查询
WITH AllNamespaces As
(
SELECT CONCAT('ns',ROW_NUMBER() OVER(ORDER BY (B.namespaceUri))) Prefix
,B.namespaceUri
FROM @xml.nodes('//*') A(nd)
CROSS APPLY(VALUES(A.nd.value('namespace-uri(.)','nvarchar(max)')))B(namespaceUri)
WHERE LEN(B.namespaceUri)>0
GROUP BY B.namespaceUri
)
,recCte AS
(
SELECT 1 AS NestLevel
,ROW_NUMBER() OVER(ORDER BY A.nd) AS ElementPosition
,CAST(REPLACE(STR(ROW_NUMBER() OVER(ORDER BY A.nd),5),' ','0') AS VARCHAR(900)) COLLATE DATABASE_DEFAULT AS SortString
,CONCAT(ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)'),'[',ROW_NUMBER() OVER(PARTITION BY ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)') ORDER BY A.nd),']') AS FullName
,CAST(CONCAT('/',ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)'),'[',ROW_NUMBER() OVER(PARTITION BY ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)') ORDER BY A.nd),']') AS NVARCHAR(MAX)) COLLATE DATABASE_DEFAULT AS XPath
,A.nd.value('text()[1]','nvarchar(max)') AS NodeValue
,A.nd.query('./*') NextFragment
FROM @xml.nodes('/*') A(nd)
LEFT JOIN AllNamespaces ns ON ns.namespaceUri=A.nd.value('namespace-uri(.)','nvarchar(max)')
UNION ALL
SELECT r.NestLevel+1
,ROW_NUMBER() OVER(ORDER BY A.nd)
,CAST(CONCAT(r.SortString,REPLACE(STR(ROW_NUMBER() OVER(ORDER BY A.nd),5),' ','0')) AS VARCHAR(900)) COLLATE DATABASE_DEFAULT
,CONCAT(ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)'),'[',ROW_NUMBER() OVER(PARTITION BY ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)') ORDER BY A.nd),']') AS FullName
,CONCAT(r.XPath,'/',ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)'),'[',ROW_NUMBER() OVER(PARTITION BY ns.Prefix+':',A.nd.value('local-name(.)','nvarchar(max)') ORDER BY A.nd),']') AS FullName
,A.nd.value('text()[1]','nvarchar(max)') AS NodeValue
,A.nd.query('./*') NextFragment
FROM recCte r
CROSS APPLY NextFragment.nodes('*') A(nd)
INNER JOIN AllNamespaces ns ON ns.namespaceUri=A.nd.value('namespace-uri(.)','nvarchar(max)')
)
SELECT *
FROM recCte
WHERE NodeValue IS NOT NULL
ORDER BY SortString;
-结果/ *
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
| NestLevel | ElementPosition | SortString | FullName | XPath | NodeValue | NextFragment |
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
| 4 | 1 | 00001000010000100001 | ns2:orderDate[1] | /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderDate[1] | 2020-03-16T10:30:56.000Z | |
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
| 6 | 1 | 000010000100001000020000100001 | ns4:customerServiceIdentifier[1] | /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:customerServiceIdentifier[1] | ETHA15302121 | |
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
| 8 | 1 | 0000100001000010000200001000020000100001 | ns4:code[1] | /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:instanceCharacteristic[1]/ns4:action[1]/ns4:code[1] | Modify | |
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
| 8 | 1 | 0000100001000010000200001000020000200001 | ns4:value[1] | /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:instanceCharacteristic[1]/ns4:instanceIdentifier[1]/ns4:value[1] | OS014-AHEFV5T9 | |
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
| 4 | 3 | 00001000010000100003 | ns2:orderVersion[1] | /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderVersion[1] | 1 | |
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
| 3 | 2 | 000010000100002 | ns1:wiAction[1] | /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiAction[1] | Create | |
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
| 3 | 3 | 000010000100003 | ns1:wiVersion[1] | /root[1]/ns1:manageWorkItemRequest[1]/ns1:wiVersion[1] | 1 | |
+-----------+-----------------+------------------------------------------+----------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------+--------------+
* /
-仅显示所创建的XPath可以按预期工作:
WITH XMLNAMESPACES('dummy1' AS ns1,'dummy2' AS ns2,'dummy3' AS ns3,'dummy4' AS ns4,'dummy5' AS ns5)
SELECT @xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderDate[1]','nvarchar(max)')
,@xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:customerServiceIdentifier[1]','nvarchar(max)')
,@xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:instanceCharacteristic[1]/ns4:action[1]/ns4:code[1]','nvarchar(max)')
,@xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderItem[1]/ns3:instance[1]/ns4:instanceCharacteristic[1]/ns4:instanceIdentifier[1]/ns4:value[1]','nvarchar(max)')
,@xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiFocus[1]/ns2:orderVersion[1]','nvarchar(max)')
,@xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiAction[1]','nvarchar(max)')
,@xml.value('/root[1]/ns1:manageWorkItemRequest[1]/ns1:wiVersion[1]','nvarchar(max)');
简而言之:
APPLY
和.nodes()
可以返回嵌套节点,此操作就会继续。