Конкатенация XML без ввода типа в строку

У меня есть следующий XML, сгенерированный из различных таблиц в базе данных SQL SERVER

<XMLData>
...
<Type>1</Type>
...
</XMLData>

и

<XMLData>
...
<Type>2</Type>
...
</XMLData>

и

<XMLData>
...
<Type>3</Type>
...
</XMLData>

Конечный результат, который мне нужен, объединен следующим образом:

<AllMyData>
    <XMLData>
        ...
        <Type>1</Type>
        ...
    </XMLData>
    <XMLData>
        ...
        <Type>2</Type>
        ...
    </XMLData>
    <XMLData>
        ...
        <Type>3</Type>
        ...
    </XMLData>
<AllMyData>

ПРИМЕЧАНИЕ. Все независимые элементы, которые я объединяю, имеют одно и то же имя тега.

Заранее благодарим за это.

Ответы

Ответ 1

У меня есть следующий XML, сгенерированный из различных таблиц в моем SQL База данных SERVER

В зависимости от того, как вы его используете, но если он находится в переменной XML, вы можете сделать это.

declare @XML1 xml
declare @XML2 xml
declare @XML3 xml

set @XML1 = '<XMLData><Type>1</Type></XMLData>'
set @XML2 = '<XMLData><Type>2</Type></XMLData>'
set @XML3 = '<XMLData><Type>3</Type></XMLData>'

select @XML1, @XML2, @XML3 
for xml path('AllMyData')

Ответ 2

Я не могу комментировать, но могу ответить так, хотя я думаю, что комментарий более уместен, я расскажу о том, что дождевик ответил выше, чтобы добавить немного больше контроля. Мой .Net-код должен знать имя столбца, которое было возвращено, поэтому я не могу полагаться на автоматически сгенерированные имена, но нуждался в самом конце rainabba, указанном выше.

Таким образом, xml может быть эффективно объединен в одну строку и получившийся столбец. Вы можете использовать этот же подход, чтобы присвоить результаты переменной XML и вернуть ее из PROC.

SELECT (
 SELECT XmlData as [*]
 FROM
     (
     SELECT
         xmlResult AS [*]
     FROM
         @XmlRes
     WHERE
         xmlResult IS NOT NULL
     FOR XML PATH(''), TYPE
     ) as DATA(XmlData)
 FOR XML PATH('')
) as [someColumnName]

Ответ 3

Если вы используете for xml type, вы можете комбинировать столбцы XML, не отбрасывая их. Например:

select  *
from    (
        select  (
                select  1 as Type
                for xml path(''), type
                )
        union all
        select  (
                select  2 as Type
                for xml path(''), type
                )
        union all
        select  (
                select  3 as Type
                for xml path(''), type
                )
        ) as Data(XmlData)
for xml path(''), root('AllMyData'), type

Отпечатки:

<AllMyData>
    <XmlData>
        <Type>1</Type>
    </XmlData>
    <XmlData>
        <Type>2</Type>
    </XmlData>
    <XmlData>
        <Type>3</Type>
    </XmlData>
</AllMyData>

Ответ 4

В качестве дополнения к Mikael Eriksson answer - Если у вас есть процесс, когда вам нужно постоянно добавлять узлы, а затем хотите сгруппировать его под одним node, это один из способов сделать это:

declare @XML1 XML
declare @XML2 XML
declare @XML3 XML
declare @XMLSummary XML

set @XML1 = '<XMLData><Type>1</Type></XMLData>'
set @XMLSummary = (SELECT @XMLSummary, @XML1 FOR XML PATH(''))

set @XML2 = '<XMLData><Type>2</Type></XMLData>'
set @XMLSummary = (SELECT @XMLSummary, @XML2 FOR XML PATH(''))

set @XML3 = '<XMLData><Type>3</Type></XMLData>'
set @XMLSummary = (SELECT @XMLSummary, @XML3 FOR XML PATH(''))


SELECT @XMLSummary FOR XML PATH('AllMyData')

Ответ 5

Мне нужно было сделать то же самое, но не зная, сколько строк/переменных было затронуто, и без добавления дополнительной схемы, поэтому здесь было мое решение. Следуя этому шаблону, я могу сгенерировать столько фрагментов, сколько захочу, объединить их, передать их между PROCS или даже вернуть их из procs и в любой момент, обернуть их в контейнеры без изменения данных или принудительно добавить XML-структуру в мои данные. Я использую этот подход с конечными точками HTTP для предоставления веб-сервисов XML и с помощью другого трюка, который преобразует XML в JSON для предоставления JSON WebServices.

    -- SETUP A type (or use this design for a Table Variable) to temporarily store snippets into. The pattern can be repeated to pass/store snippets to build
    -- larger elements and those can be further combined following the pattern.
    CREATE TYPE [dbo].[XMLRes] AS TABLE(
        [xmlResult] [xml] NULL
    )
    GO


    -- Call the following as much as you like to build up all the elements you want included in the larger element
    INSERT INTO @XMLRes ( xmlResult )
        SELECT
            (    
                SELECT
                    'foo' '@bar'
                FOR XML
                    PATH('SomeTopLevelElement')
            )

    -- This is the key to "concatenating" many snippets into a larger element. At the end of this, add " ,ROOT('DocumentRoot') " to wrapp them up in another element even
    -- The outer select is a time from user2503764 that controls the output column name

   SELECT (
    SELECT XmlData as [*]
    FROM
        (
        SELECT
            xmlResult AS [*]
        FROM
            @XmlRes
        WHERE
            xmlResult IS NOT NULL
        FOR XML PATH(''), TYPE
        ) as DATA(XmlData)
    FOR XML PATH('')
   ) as [someColumnName]

Ответ 6

alter ПРОЦЕДУРА usp_fillHDDT @Code int

А.С. НАЧАТЬ

DECLARE @HD XML, @DT XML;

SET NOCOUNT ON;
select invhdcode, invInvoiceNO,invDate,invCusCode,InvAmount into #HD
from dbo.trnInvoiceHD where [email protected]

select invdtSlNo No,invdtitemcode ItemCode,invdtitemcode ItemName,
invDtRate Rate,invDtQty Qty,invDtAmount Amount ,'Kg' Unit into #DT from
 dbo.trnInvoiceDt  where [email protected] 

set @HD = (select * from #HD HD  FOR XML AUTO,ELEMENTS XSINIL);
set @DT = (select* from #DT DT FOR XML AUTO,ELEMENTS XSINIL);

SELECT CAST ('<OUTPUT>'+ CAST (ISNULL(@HD,'') AS VARCHAR(MAX))+ CAST ( ISNULL(@DT,'') AS VARCHAR(MAX))+ '</OUTPUT>'   AS XML)

КОНЕЦ

Ответ 7

public String ReplaceSpecialChar(String inStr)
{
    inStr = inStr.Replace("&", "&amp;");
    inStr = inStr.Replace("<", "&lt;");
    inStr = inStr.Replace(">", "&gt;");
    inStr = inStr.Replace("'", "&#39;");
    inStr = inStr.Replace("\"", "&quot;");
    return inStr;
}