【问题标题】:T-SQL cannot query XML with multiple nested namespaces and no unique IDT-SQL 无法查询具有多个嵌套命名空间且没有唯一 ID 的 XML
【发布时间】:2019-02-18 01:50:30
【问题描述】:

我需要从一个包含 4 个命名空间但它们都没有唯一 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

【问题讨论】:

    标签: sql-server xml tsql xml-namespaces


    【解决方案1】:

    您已经定义了命名空间 - 但您从未在 XPath 中使用它们!另外,我强烈建议使用内置的 XQuery 功能,而不是旧的 OPENXML 方法。

    试试这个选择语句:

    ;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,要么你正在使用不同的代码......

    【讨论】:

    • 感谢 select 语句,但它没有返回任何数据。我在此链接中提供了 XML 结构的屏幕截图 - imgur.com/a/tJ0ApS7 此外,“root”似乎是 T-SQL 中的保留字,但更改它也不会返回任何数据..
    • @Walkdog:对于您在问题中显示的 XML,我提供的代码确实有效。看我的更新。所以我的猜测是您尝试使用此代码的 XML 与您在此处发布的示例的结构不同(尤其是 XML 命名空间)
    • 我很抱歉 - 你是对的。我试图使用已删除名称空间的 XML 运行该语句。该脚本确实可以在原始文件上完美运行。非常感谢。
    猜你喜欢
    • 2014-05-14
    • 2012-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 2018-06-20
    • 2021-11-23
    • 2017-04-29
    相关资源
    最近更新 更多