T-SQL 无法查询具有多个嵌套命名空间且没有唯一 ID 的 XML
T-SQL cannot query XML with multiple nested namespaces and no unique ID
我需要从包含 4 个命名空间但其中 none 个具有唯一 ID 的 xml 文件创建查询。例如。 xmlns:fb
我在下面列出了它们:
xmlns="http://xxx/pie/svc/frs/FindRegistration/2.0.0"
xmlns="http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0"
xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0"
xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0"
如果我从文档中删除所有命名空间(通过 Visual Studio),我可以很好地检索数据,但我需要保持命名空间完好无损。
<FindRegistrationsResponse xmlns="http://xxx/pie/svc/frs/FindRegistration/2.0.0">
<AuditDetails xmlns="http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0">
<QueryIdentifier xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">8901823</QueryIdentifier>
<PractitionerCount xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">134140</PractitionerCount>
<ServiceMessagesCount xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">2</ServiceMessagesCount>
<TotalRecordsSearched xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">134142</TotalRecordsSearched>
<TotalNumberOfRegistration xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">257034</TotalNumberOfRegistration>
<SnapshotDate xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">2018-06-29</SnapshotDate>
</AuditDetails>
<ProfessionNumberReplay ProfessionNumber="MED0000xxxxx" xmlns="http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0">
<Practitioner>
<PractitionerIdentifier xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">xxxxxxxx</PractitionerIdentifier>
<PractitionerName NameEditDate="2010-07-03T14:14:35.377" xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<NameTitle>Dr</NameTitle>
<FamilyName>Smith</FamilyName>
<GivenName>John</GivenName>
<MiddleName />
</PractitionerName>
<Demographics xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<Gender>GenderName</Gender>
</Demographics>
<Qualification QualificationEditDate="2016-08-10T19:35:54.067" xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<QualificationTitle>Bachelor of Medicine / Bachelor of Surgery </QualificationTitle>
<AwardingInstitution>University of xxx</AwardingInstitution>
<CountryQualificationObtained>Country Name</CountryQualificationObtained>
<YearOfQualification>1999</YearOfQualification>
</Qualification>
<Address AddressEditDate="2010-07-03T14:15:48.607" xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<AustralianAddress>
<AustralianLocality>SUBURB NAME</AustralianLocality>
<AustralianPostcode>2000</AustralianPostcode>
<AustralianState>NSW</AustralianState>
<Country>Australia</Country>
</AustralianAddress>
</Address>
<Profession xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<ProfessionNumber>MED0000xxxxx</ProfessionNumber>
<Profession>Medical Practitioner</Profession>
<ProfessionStartDate>1999-05-10T00:00:00</ProfessionStartDate>
<Registration>
<RecordNumber>001</RecordNumber>
<RegistrationType>Limited (Public Interest - Occasional Practice)</RegistrationType>
<RegistrationStatus>Unregistered</RegistrationStatus>
<RegistrationSubStatus>Withdrawn</RegistrationSubStatus>
<RegistrationToDate>2013-09-30T00:00:00</RegistrationToDate>
<InitialRegistrationDate>1965-05-10T00:00:00</InitialRegistrationDate>
</Registration>
<Condition ConditionEditDate="2012-10-22T14:00:10.5">
<ConditionType>Registration</ConditionType>
<ConditionDetail>text here</ConditionDetail>
</Condition>
</Profession>
</Practitioner>
</ProfessionNumberReplay>
</FindRegistrationsResponse>
这是我试过的 T-SQL 代码:
DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @XML = XMLData FROM AHPRA_XML
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
;WITH XMLNAMESPACES('http://xxx/pie/svc/frs/FindRegistration/2.0.0',
'http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0',
'http://xxx/pie/xsd/common/CommonCoreElements/2.0.0',
'http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0')
SELECT DISTINCT ProfessionNumber, NameTitle, GivenName, MiddleName, FamilyName, Gender
FROM OPENXML(@hDoc, 'FindRegistrationsResponse/ProfessionNumberReplay/Practitioner')
WITH
(
ProfessionNumber [varchar](50) '../@ProfessionNumber',
NameTitle [varchar](20) 'PractitionerName/NameTitle',
GivenName [varchar](100) 'PractitionerName/GivenName',
MiddleName [varchar](100) 'PractitionerName/MiddleName',
FamilyName [varchar](100) 'PractitionerName/FamilyName',
Gender [varchar](10) 'Demographics/Gender'
)
EXEC sp_xml_removedocument @hDoc
GO
您已经定义了名称空间 - 但您从未在 XPath 中使用它们!此外,我强烈建议使用内置的 XQuery 功能,而不是传统的 OPENXML
方法。
试试这个 select 语句:
;WITH XMLNAMESPACES('http://xxx/pie/svc/frs/FindRegistration/2.0.0' AS root,
'http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0' AS msg,
'http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0' AS el)
SELECT
ProfessionNumber = XC.value('(../@ProfessionNumber)', 'varchar(50)'),
NameTitle = XC.value('(el:PractitionerName/el:NameTitle)[1]', 'varchar(50)'),
GivenName = XC.value('(el:PractitionerName/el:GivenName)[1]', 'varchar(50)'),
MiddleName = XC.value('(el:PractitionerName/el:MiddleName)[1]', 'varchar(50)'),
FamilyName = XC.value('(el:PractitionerName/el:FamilyName)[1]', 'varchar(50)'),
Gender = XC.value('(el:Demographics/el:Gender)[1]', 'varchar(50)')
FROM
@XML.nodes('/root:FindRegistrationsResponse/msg:ProfessionNumberReplay/msg:Practitioner') AS XT(XC)
这应该从 XML 字符串中获取所需的数据。
更新:
当您在问题中提供的 XML 和此处的代码时,您 会得到 这个输出:
所以要么你没有真正使用你提供的示例 XML,要么你使用了不同的代码......
我需要从包含 4 个命名空间但其中 none 个具有唯一 ID 的 xml 文件创建查询。例如。 xmlns:fb
我在下面列出了它们:
xmlns="http://xxx/pie/svc/frs/FindRegistration/2.0.0"
xmlns="http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0"
xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0"
xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0"
如果我从文档中删除所有命名空间(通过 Visual Studio),我可以很好地检索数据,但我需要保持命名空间完好无损。
<FindRegistrationsResponse xmlns="http://xxx/pie/svc/frs/FindRegistration/2.0.0">
<AuditDetails xmlns="http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0">
<QueryIdentifier xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">8901823</QueryIdentifier>
<PractitionerCount xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">134140</PractitionerCount>
<ServiceMessagesCount xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">2</ServiceMessagesCount>
<TotalRecordsSearched xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">134142</TotalRecordsSearched>
<TotalNumberOfRegistration xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">257034</TotalNumberOfRegistration>
<SnapshotDate xmlns="http://xxx/pie/xsd/common/CommonCoreElements/2.0.0">2018-06-29</SnapshotDate>
</AuditDetails>
<ProfessionNumberReplay ProfessionNumber="MED0000xxxxx" xmlns="http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0">
<Practitioner>
<PractitionerIdentifier xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">xxxxxxxx</PractitionerIdentifier>
<PractitionerName NameEditDate="2010-07-03T14:14:35.377" xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<NameTitle>Dr</NameTitle>
<FamilyName>Smith</FamilyName>
<GivenName>John</GivenName>
<MiddleName />
</PractitionerName>
<Demographics xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<Gender>GenderName</Gender>
</Demographics>
<Qualification QualificationEditDate="2016-08-10T19:35:54.067" xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<QualificationTitle>Bachelor of Medicine / Bachelor of Surgery </QualificationTitle>
<AwardingInstitution>University of xxx</AwardingInstitution>
<CountryQualificationObtained>Country Name</CountryQualificationObtained>
<YearOfQualification>1999</YearOfQualification>
</Qualification>
<Address AddressEditDate="2010-07-03T14:15:48.607" xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<AustralianAddress>
<AustralianLocality>SUBURB NAME</AustralianLocality>
<AustralianPostcode>2000</AustralianPostcode>
<AustralianState>NSW</AustralianState>
<Country>Australia</Country>
</AustralianAddress>
</Address>
<Profession xmlns="http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0">
<ProfessionNumber>MED0000xxxxx</ProfessionNumber>
<Profession>Medical Practitioner</Profession>
<ProfessionStartDate>1999-05-10T00:00:00</ProfessionStartDate>
<Registration>
<RecordNumber>001</RecordNumber>
<RegistrationType>Limited (Public Interest - Occasional Practice)</RegistrationType>
<RegistrationStatus>Unregistered</RegistrationStatus>
<RegistrationSubStatus>Withdrawn</RegistrationSubStatus>
<RegistrationToDate>2013-09-30T00:00:00</RegistrationToDate>
<InitialRegistrationDate>1965-05-10T00:00:00</InitialRegistrationDate>
</Registration>
<Condition ConditionEditDate="2012-10-22T14:00:10.5">
<ConditionType>Registration</ConditionType>
<ConditionDetail>text here</ConditionDetail>
</Condition>
</Profession>
</Practitioner>
</ProfessionNumberReplay>
</FindRegistrationsResponse>
这是我试过的 T-SQL 代码:
DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX)
SELECT @XML = XMLData FROM AHPRA_XML
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML
;WITH XMLNAMESPACES('http://xxx/pie/svc/frs/FindRegistration/2.0.0',
'http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0',
'http://xxx/pie/xsd/common/CommonCoreElements/2.0.0',
'http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0')
SELECT DISTINCT ProfessionNumber, NameTitle, GivenName, MiddleName, FamilyName, Gender
FROM OPENXML(@hDoc, 'FindRegistrationsResponse/ProfessionNumberReplay/Practitioner')
WITH
(
ProfessionNumber [varchar](50) '../@ProfessionNumber',
NameTitle [varchar](20) 'PractitionerName/NameTitle',
GivenName [varchar](100) 'PractitionerName/GivenName',
MiddleName [varchar](100) 'PractitionerName/MiddleName',
FamilyName [varchar](100) 'PractitionerName/FamilyName',
Gender [varchar](10) 'Demographics/Gender'
)
EXEC sp_xml_removedocument @hDoc
GO
您已经定义了名称空间 - 但您从未在 XPath 中使用它们!此外,我强烈建议使用内置的 XQuery 功能,而不是传统的 OPENXML
方法。
试试这个 select 语句:
;WITH XMLNAMESPACES('http://xxx/pie/svc/frs/FindRegistration/2.0.0' AS root,
'http://xxx/pie/xsd/frs/FindRegistrationMessages/2.0.0' AS msg,
'http://xxx/pie/xsd/frs/PractitionerRegistrationElements/2.0.0' AS el)
SELECT
ProfessionNumber = XC.value('(../@ProfessionNumber)', 'varchar(50)'),
NameTitle = XC.value('(el:PractitionerName/el:NameTitle)[1]', 'varchar(50)'),
GivenName = XC.value('(el:PractitionerName/el:GivenName)[1]', 'varchar(50)'),
MiddleName = XC.value('(el:PractitionerName/el:MiddleName)[1]', 'varchar(50)'),
FamilyName = XC.value('(el:PractitionerName/el:FamilyName)[1]', 'varchar(50)'),
Gender = XC.value('(el:Demographics/el:Gender)[1]', 'varchar(50)')
FROM
@XML.nodes('/root:FindRegistrationsResponse/msg:ProfessionNumberReplay/msg:Practitioner') AS XT(XC)
这应该从 XML 字符串中获取所需的数据。
更新:
当您在问题中提供的 XML 和此处的代码时,您 会得到 这个输出:
所以要么你没有真正使用你提供的示例 XML,要么你使用了不同的代码......