18

TSQL で定義済みの xml (具体的には xsd) を変更しようとしています。xsd 要素の 1 つに列挙制限を挿入したいと考えています。

タスクは、クエリの例に基づいて 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" />

誰でも助けることができますか?

4

3 に答える 3

2

期待していたよりも少し醜いものになりました。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 XMLwithを使用することです。ROOTそうしないと、要素をxs:enumeration後で再作成する必要があります。

2 つのソリューション

.modify()3回使用

アイデア:

  1. どこかから(不要なルートを含む)すべてを@enumeration他のxmlに挿入します
  2. 必要なコンテンツを適切な場所にコピーします
  3. の不要になったコピーを削除@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

が作成される部分を変更できる場合は、 fromとして直接@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;
于 2017-01-04T10:28:01.387 に答える
0

XML がそれほど複雑でない場合は、代わりに FOR XML EXPLICIT を使用してみませんか?

もう 1 つの回避策は、名前空間なしで XML を生成し、後で追加することです。

于 2013-04-23T15:09:51.363 に答える
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)
于 2012-12-10T23:28:20.940 に答える