我尝试使用T-SQL's OPENXML
函数将XML解析为表格形式,但在存在命名空间属性的情况下,我一直会遇到误导性错误。
例如,SQL Server声称有关这个格式良好的XML文档的内容如下:
DECLARE @hdoc int;
DECLARE @doc varchar(1000);
SET @doc =
'
<?xml version="1.0" encoding="UTF-8"?>
<Data xmlns="http://www.digitalmeasures.com/schema/data" xmlns:dmd="http://www.digitalmeasures.com/schema/data-metadata" dmd:date="2016-06-13">
<Record userId="123456" username="jeffp" termId="129" dmd:surveyId="1234567">
<dmd:IndexEntry indexKey="AACSBSUFF" entryKey="Participating" text="Participating"/>
<dmd:IndexEntry indexKey="DEPARTMENT" entryKey="WCBD" text="WCBD"/>
<dmd:IndexEntry indexKey="QUALIFICATION" entryKey="Instructional Practitioner" text="Instructional Practitioner"/>
<dmd:IndexEntry indexKey="RANK" entryKey="Academic Staff" text="Academic Staff"/>
<GENSERVE id="33426841601" dmd:lastModified="2011-03-15T10:23:01" dmd:startDate="2010-07-01">
<TYPE>University</TYPE>
<TYPEOTHER/>
<ORG>University Academic Advising Council </ORG>
<ROLE>Committee Member</ROLE>
<ROLEOTHER/>
<OFFICE>President/Elect/Past</OFFICE>
<RESPONSIBILITIES/>
<NUMHOURS/>
<ELECAPP>Elected</ELECAPP>
<AUDIENCE>Local</AUDIENCE>
<EXOFFICIO/>
<DTM_START>July</DTM_START>
<DTD_START/>
<DTY_START>2010</DTY_START>
<START_START>2010-07-01</START_START>
<START_END>2010-07-31</START_END>
<DTM_END/>
<DTD_END/>
<DTY_END/>
<END_START></END_START>
<END_END></END_END>
</GENSERVE>
</Record>
</Data>
';
EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc;
SELECT *
FROM OPENXML (@hdoc, '/Data/Record/GENSERVE', 2)
with(TYPE varchar(250),
ORG varchar(250) )
exec sp_xml_removedocument @hdoc;
The XML parse error 0xc00ce55e occurred on line number 20, near the XML text " <AUDIEN". The error description is 'Element was not closed.'.
嗯,这太荒谬了,因为如果我只是删除这些行:
<dmd:IndexEntry indexKey="AACSBSUFF" entryKey="Participating" text="Participating"/>
<dmd:IndexEntry indexKey="DEPARTMENT" entryKey="WCBD" text="WCBD"/>
<dmd:IndexEntry indexKey="QUALIFICATION" entryKey="Instructional Practitioner" text="Instructional Practitioner"/>
<dmd:IndexEntry indexKey="RANK" entryKey="Academic Staff" text="Academic Staff"/>
然后我没有错误 - 但也没有数据 - 只是空列。
只有当我浏览并删除对任何命名空间的每个引用时,它才会起作用。
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Record userId="123456" username="jeffp" termId="129">
<GENSERVE id="33426841601" >
<TYPE>University</TYPE>
<TYPEOTHER/>
<ORG>University Academic Advising Council </ORG>
<ROLE>Committee Member</ROLE>
<ROLEOTHER/>
<OFFICE>President/Elect/Past</OFFICE>
<RESPONSIBILITIES/>
<NUMHOURS/>
<ELECAPP>Elected</ELECAPP>
<AUDIENCE>Local</AUDIENCE>
<EXOFFICIO/>
<DTM_START>July</DTM_START>
<DTD_START/>
<DTY_START>2010</DTY_START>
<START_START>2010-07-01</START_START>
<START_END>2010-07-31</START_END>
<DTM_END/>
<DTD_END/>
<DTY_END/>
<END_START></END_START>
<END_END></END_END>
</GENSERVE>
</Record>
</Data>
TYPE ORG University University Academic Advising Council
我怎样才能读入命名空间属性?
答案 0 :(得分:2)
您的XML字符串被截断,因为其长度超过varchar(1000)
,因此XML解析错误。错误消息与命名空间无关。
现在出现命名空间问题。请注意,您的XML具有默认命名空间(声明的命名空间不带前缀)。查询中涉及的所有元素都隐式地从Data
元素继承默认命名空间。您需要将前缀映射到默认命名空间URI,并使用该前缀在OPENXML查询中引用命名空间中的元素:
DECLARE @doc varchar(5000);
.....
EXEC sp_xml_preparedocument @hdoc OUTPUT,
@doc,
'<Data xmlns:d="http://www.digitalmeasures.com/schema/data" />';
SELECT *
FROM OPENXML (@hdoc, '/d:Data/d:Record/d:GENSERVE', 2)
with(TYPE varchar(250) 'd:TYPE',
ORG varchar(250) 'd:ORG' )
如果在SQL Server版本中可用,您可能需要考虑使用SQL Server的XQuery和XML数据类型:
DECLARE @xml XML = 'your xml string here'
;WITH XMLNAMESPACES (DEFAULT 'http://www.digitalmeasures.com/schema/data' )
SELECT
t.c.value('TYPE[1]', 'VARCHAR(100)' ) AS TYPE,
t.c.value( 'ORG[1]', 'VARCHAR(100)' ) AS ORG
FROM @xml.nodes('/Data/Record/GENSERVE') t(c)