我有一块XML,我必须在SQL Server中粉碎。到目前为止,我已经取得了部分成功,但是尽管我在网上找到并尝试了几个小时的代码,但我已经没有进一步了......
在SQL代码下面,包括XML的修剪部分:
DECLARE @xml xml, @hdoc int
SET @xml = '
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.egem.nl/StUF/StUF0301" xmlns:ns2="http://www.egem.nl/StUF/sector/zkn/0310" xmlns:bg="http://www.egem.nl/StUF/sector/bg/0310">
<SOAP-ENV:Body>
<ns2:zakLk01>
<ns2:object ns1:entiteittype="ZAK" ns1:verwerkingssoort="T">
<ns2:heeftBetrekkingOp ns1:entiteittype="ZAKOBJ" ns1:verwerkingssoort="T">
<ns2:gerelateerde>
<ns2:natuurlijkPersoon ns1:entiteittype="NPS" ns1:verwerkingssoort="I">
<verblijfsadres xmlns="http://www.egem.nl/StUF/sector/bg/0310">
<gor.openbareRuimteNaam>Westmalledreef 45</gor.openbareRuimteNaam>
<wpl.woonplaatsNaam>B-16753</wpl.woonplaatsNaam>
</verblijfsadres>
<voornamen xmlns="http://www.egem.nl/StUF/sector/bg/0310">Erik</voornamen>
</ns2:natuurlijkPersoon>
</ns2:gerelateerde>
</ns2:heeftBetrekkingOp>
</ns2:object>
</ns2:zakLk01>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
'
EXEC sp_xml_preparedocument
@hDoc OUTPUT,
@XML,
'<root xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.egem.nl/StUF/StUF0301"
xmlns:ns2="http://www.egem.nl/StUF/sector/zkn/0310"
xmlns:bg="http://www.egem.nl/StUF/sector/bg/0310>"/>'
SELECT * FROM OPENXML(@hdoc, '/SOAP-ENV:Envelope') --Row Pattern
WITH
(
Voornamen VARCHAR(50) './/ns2:heeftBetrekkingOp/ns2:gerelateerde/ns2:natuurlijkPersoon/bg:voornamen',
Adres VARCHAR(100) './/ns2:heeftBetrekkingOp/ns2:gerelateerde/ns2:natuurlijkPersoon/bg:verblijfsadres/bg:gor.openbareRuimteNaam'
)
EXEC sp_xml_removedocument @hdoc --Releasing memory
当我使用同一段XML在https://www.freeformatter.com/xpath-tester.html上尝试两个XPath查询时,它们工作得很好,并且还给了我“voornamen”和“openbareRuimteNaam”的值。在SQL中,无论我尝试什么,它们都会返回NULL。我一定做错了什么。有人能指出我正确的方向吗?
我已经尝试过SQL Server 2014以及2016年。
答案 0 :(得分:1)
您可以使用 Configuration cfg = new Configuration()
.addAnnotatedClass(org.entity.Person.class);
方法代替.value
。
示例解决方案:
OPENXML
当然深度搜索;WITH XMLNAMESPACES (
'http://schemas.xmlsoap.org/soap/envelope/' AS [SOAP-ENV],
'http://www.egem.nl/StUF/StUF0301' AS ns1,
'http://www.egem.nl/StUF/sector/zkn/0310' AS ns2,
'http://www.egem.nl/StUF/sector/bg/0310' AS bg
)
SELECT @xml.value('(//bg:voornamen/text())[1]','VARCHAR(50)') AS Voornamen,
@xml.value('(//bg:gor.openbareRuimteNaam/text())[1]','VARCHAR(100)') AS Adres
不是好习惯。更好的是指定每个节点号:
//
答案 1 :(得分:0)
这个XML是如何生成的?你遇到的问题是:
<verblijfsadres xmlns="http://www.egem.nl/StUF/sector/bg/0310">
<gor.openbareRuimteNaam>Westmalledreef 45</gor.openbareRuimteNaam>
<wpl.woonplaatsNaam>B-16753</wpl.woonplaatsNaam>
</verblijfsadres>
<voornamen xmlns="http://www.egem.nl/StUF/sector/bg/0310">Erik</voornamen>
您使用与其他命名空间相同的URL声明新的默认命名空间。
在下面的代码中,我删除了这些额外的命名空间,并使用您的代码进行了微小的更改:voornamen
和gor.openbareRuimteNaam
没有前缀。这有效:
DECLARE @xml xml, @hdoc int
SET @xml = '
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.egem.nl/StUF/StUF0301" xmlns:ns2="http://www.egem.nl/StUF/sector/zkn/0310" xmlns:bg="http://www.egem.nl/StUF/sector/bg/0310">
<SOAP-ENV:Body>
<ns2:zakLk01>
<ns2:object ns1:entiteittype="ZAK" ns1:verwerkingssoort="T">
<ns2:heeftBetrekkingOp ns1:entiteittype="ZAKOBJ" ns1:verwerkingssoort="T">
<ns2:gerelateerde>
<ns2:natuurlijkPersoon ns1:entiteittype="NPS" ns1:verwerkingssoort="I">
<verblijfsadres>
<gor.openbareRuimteNaam>Westmalledreef 45</gor.openbareRuimteNaam>
<wpl.woonplaatsNaam>B-16753</wpl.woonplaatsNaam>
</verblijfsadres>
<voornamen>Erik</voornamen>
</ns2:natuurlijkPersoon>
</ns2:gerelateerde>
</ns2:heeftBetrekkingOp>
</ns2:object>
</ns2:zakLk01>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
'
EXEC sp_xml_preparedocument
@hDoc OUTPUT,
@XML,
'<root xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.egem.nl/StUF/StUF0301"
xmlns:ns2="http://www.egem.nl/StUF/sector/zkn/0310"
xmlns:bg="http://www.egem.nl/StUF/sector/bg/0310>"/>'
SELECT * FROM OPENXML(@hdoc, '/SOAP-ENV:Envelope') --Row Pattern
WITH
(
Voornamen VARCHAR(50) './/ns2:heeftBetrekkingOp/ns2:gerelateerde/ns2:natuurlijkPersoon/voornamen',
Adres VARCHAR(100) './/ns2:heeftBetrekkingOp/ns2:gerelateerde/ns2:natuurlijkPersoon/verblijfsadres/gor.openbareRuimteNaam'
)
EXEC sp_xml_removedocument @hdoc --Releasing memory
尝试不使用WITH
这样的原始查询
SELECT * FROM OPENXML(@hdoc, '/SOAP-ENV:Envelope')
您将获得一个列表,XML引擎如何看待您的元素(片段):
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| natuurlijkPersoon | ns2 | http://www.egem.nl/StUF/sector/zkn/0310 | NULL | NULL | NULL |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| entiteittype | ns1 | http://www.egem.nl/StUF/StUF0301 | NULL | NULL | NULL |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| #text | NULL | NULL | NULL | NULL | NPS |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| verwerkingssoort | ns1 | http://www.egem.nl/StUF/StUF0301 | NULL | NULL | NULL |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| #text | NULL | NULL | NULL | NULL | I |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| verblijfsadres | NULL | http://www.egem.nl/StUF/sector/bg/0310 | NULL | NULL | NULL |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| xmlns | xmlns | NULL | NULL | NULL | NULL |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| #text | NULL | NULL | NULL | NULL | http://www.egem.nl/StUF/sector/bg/0310 |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| gor.openbareRuimteNaam | NULL | http://www.egem.nl/StUF/sector/bg/0310 | NULL | NULL | NULL |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| #text | NULL | NULL | NULL | NULL | Westmalledreef 45 |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| wpl.woonplaatsNaam | NULL | http://www.egem.nl/StUF/sector/bg/0310 | NULL | 20 | NULL |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| #text | NULL | NULL | NULL | NULL | B-16753 |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
| voornamen | NULL | http://www.egem.nl/StUF/sector/bg/0310 | NULL | 18 | NULL |
+------------------------+-------+-----------------------------------------+------+------+----------------------------------------+
您可以看到,您要查找的元素位于命名空间中,但没有前缀...
所有这些只是解释为什么您的查询不起作用的一些原因。但是:
FROM OPENXML
与相应的SP准备和删除文档已经过时,不应再使用(很少有例外)。而是使用适当的methods the XML data type provides。
尽可能明确,最好是这样:
;WITH XMLNAMESPACES (
'http://schemas.xmlsoap.org/soap/envelope/' AS [SOAP-ENV],
'http://www.egem.nl/StUF/StUF0301' AS ns1,
'http://www.egem.nl/StUF/sector/zkn/0310' AS ns2,
'http://www.egem.nl/StUF/sector/bg/0310' AS bg
)
SELECT @xml.value('(SOAP-ENV:Envelope/SOAP-ENV:Body/ns2:zakLk01/ns2:object/ns2:heeftBetrekkingOp/ns2:gerelateerde/ns2:natuurlijkPersoon/bg:voornamen/text())[1]','VARCHAR(50)') AS Voornamen
,@xml.value('(SOAP-ENV:Envelope/SOAP-ENV:Body/ns2:zakLk01/ns2:object/ns2:heeftBetrekkingOp/ns2:gerelateerde/ns2:natuurlijkPersoon/bg:verblijfsadres/bg:gor.openbareRuimteNaam/text())[1]','VARCHAR(100)') AS Adres
这是简单而丑陋的
SELECT @xml.value('(//*:natuurlijkPersoon/*:voornamen/text())[1]','VARCHAR(50)') AS Voornamen
,@xml.value('(//*:natuurlijkPersoon/*:verblijfsadres/*:gor.openbareRuimteNaam/text())[1]','VARCHAR(100)') AS Adres