Ответ 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;