我正在尝试在TSQL中修改预定义的xml(xsd更具体)。 我想在其中一个xsd元素中插入枚举限制。
任务是根据查询填写xsd限制 例如:
create table #list(value nvarchar(100))
insert into #list values('item 1')
insert into #list values('item 2')
insert into #list values('item 3')
insert into #list values('item 4')
insert into #list values('item 5')
insert into #list values('item 6')
declare @enumeration as xml
;with xmlnamespaces('http://www.w3.org/2001/XMLSchema' as xs)
select @enumeration = (
select value as '@value'
from #list for xml path('xs:enumeration')
)
declare @schema xml
set @schema =
'<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="test">
<xs:element name="test" msdata:IsDataSet="true" msdata:MainDataTable="Example" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="Example">
<xs:complexType>
<xs:sequence>
<xs:element name="myList" minOccurs="1" nillable="false">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>'
set @schema.modify
('insert sql:variable("@enumeration")
into (//xs:element[@name=''myList'']/xs:simpleType/xs:restriction)[1]')
select @schema
问题是代码输出了不必要的xmlns属性
<xs:enumeration xmlns:xs="http://www.w3.org/2001/XMLSchema" value="item 1" />
有人可以帮忙吗?
答案 0 :(得分:1)
它比我希望的更难看。主要是因为我无法在sql:variable("@enumeration")/delete-me/node()
内使用.modify()
。
我假设您可以修改@enumeration
的生成,如下所示:
CREATE TABLE #list (value nvarchar(100));
INSERT INTO #list
VALUES ('item 1');
INSERT INTO #list
VALUES ('item 2');
INSERT INTO #list
VALUES ('item 3');
INSERT INTO #list
VALUES ('item 4');
INSERT INTO #list
VALUES ('item 5');
INSERT INTO #list
VALUES ('item 6');
DECLARE @enumeration AS xml;
WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema' AS xs)
SELECT @enumeration = (
SELECT value AS '@value'
FROM #list FOR XML PATH('xs:enumeration'), ROOT('delete-me'), TYPE
);
我们的想法是将FOR XML
与ROOT
一起使用,以便生成的命名空间位于不必要的根元素(可以跳过)。否则,我们必须稍后重新创建xs:enumeration
- 元素。
.modify()
三次这个想法:
@enumeration
(带有不必要的根)的所有内容插入到其他xml @enumeration
中不再需要的@schema
副本。DECLARE @schema xml;
SET @schema = '<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="test">
<xs:element name="test" msdata:IsDataSet="true" msdata:MainDataTable="Example" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="Example">
<xs:complexType>
<xs:sequence>
<xs:element name="myList" minOccurs="1" nillable="false">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>';
SET @schema.modify('insert sql:variable("@enumeration")
into /');
SET @schema.modify('declare namespace xs="http://www.w3.org/2001/XMLSchema";
insert /delete-me/node()
into (//xs:element[@name=''myList'']/xs:simpleType/xs:restriction)[1]');
SET @schema.modify('delete /delete-me');
SELECT @schema;
DROP TABLE #list;
.query()
创建@schema
如果您可以更改创建@schema
的部分,则可以@schema
直接生成.query()
@enumeration
:
DECLARE @enumeration AS xml;
WITH XMLNAMESPACES('http://www.w3.org/2001/XMLSchema' AS xs)
SELECT @enumeration = (
SELECT value AS '@value'
FROM #list FOR XML PATH('xs:enumeration'), ROOT('delete-me'), TYPE
);
DECLARE @schema xml;
SET @schema = @enumeration.query('<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="test">
<xs:element name="test" msdata:IsDataSet="true" msdata:MainDataTable="Example" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="Example">
<xs:complexType>
<xs:sequence>
<xs:element name="myList" minOccurs="1" nillable="false">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="50" />
{/delete-me/node()}
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>');
SELECT @schema;
答案 1 :(得分:0)
如果xml不是太大,你可以做一个简单的字符串替换:
DECLARE @schemaVARCHAR (MAX)
SET @schemaVARCHAR = CAST(@schema AS VARCHAR(MAX))
SET @schemaVARCHAR =
REPLACE(
@schemaVARCHAR,
'<xs:enumeration xmlns:xs="http://www.w3.org/2001/XMLSchema" value="item 1" />',
''
)
SET @schema = CAST(@schemaVARCHAR AS XML)
答案 2 :(得分:0)
如果您的XML不太复杂,为什么不使用FOR XML EXPLICIT呢?
另一种解决方法是在没有命名空间的情况下生成XML,然后再添加它。