0

I need to add an element using a variable

This works --

declare @XML xml = '
<DWDocument>
  <FileInfos>
    <ImageInfos>
      <ImageInfo id="0,0,0" nPages="0">
        <FileInfo fileName="9b7b36ac-c705-49ba-bf91-a952bdb44576.eml" dwFileName="f0.eml" type="normal" length="0" />
      </ImageInfo>
      <ImageInfo id="1,0,0" nPages="0">
        <FileInfo fileName="Response to Deficiency Letter.docx" dwFileName="f1.docx" type="normal" length="0" />
      </ImageInfo>
    </ImageInfos>
  </FileInfos>
</DWDocument>
'

SET @xml.modify ('insert <ImageInfo id="2,0,0" nPages="0"></ImageInfo>
         as last into (DWDocument/FileInfos/ImageInfos)[1]')

Gives me:

<ImageInfo id="2,0,0" nPages="0" /><ImageInfo>

BUT...

I need the '2' to be a variable

I tried:

declare @XML xml = '
<DWDocument>
  <FileInfos>
    <ImageInfos>
      <ImageInfo id="0,0,0" nPages="0">
        <FileInfo fileName="9b7b36ac-c705-49ba-bf91-a952bdb44576.eml" dwFileName="f0.eml" type="normal" length="0" />
      </ImageInfo>
      <ImageInfo id="1,0,0" nPages="0">
        <FileInfo fileName="Response to Deficiency Letter.docx" dwFileName="f1.docx" type="normal" length="0" />
      </ImageInfo>
    </ImageInfos>
  </FileInfos>
</DWDocument>
'

declare @ImageInfo_ID nvarchar(50) = '"2,0,0"'
declare @ImageInfo_nPages nvarchar(50) = '"0"'

SET @xml.modify ('insert <ImageInfo id={sql:variable("@ImageInfo_ID")}></ImageInfo>
         as last into (DWDocument/FileInfos/ImageInfos)[1]')

gives me the error:

Msg 2225, Level 16, State 1, Line 46
XQuery [modify()]: A string literal was expected
SET @xml.modify ('insert <ImageInfo id{sql:variable("@ImageInfo_ID")}></ImageInfo>
         as last into (DWDocument/FileInfos/ImageInfos)[1]')

gives me the error

Msg 2205, Level 16, State 1, Line 48
XQuery [modify()]: "=" was expected.
SET @xml.modify ('insert <ImageInfo>{sql:variable("@ImageInfo_ID")}</ImageInfo>
         as last into (DWDocument/FileInfos/ImageInfos)[1]')

has no error but the data is wrong, gives me

<ImageInfo>"2,0,0" nPages="0"</ImageInfo>

the 'id=' is missing

How do I specify the attribute name? id=@ImageInfo_ID?

What I REALLY NEED is

<ImageInfo id=@ImageInfo_ID nPages=@ImageInfo_nPages></ImageInfo>

to get to

<ImageInfo id="2,0,0" nPages="0"></ImageInfo>

What am I missing?

  • While asking a question, you need to provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example): (1) DDL and sample data population, i.e. CREATE table(s) plus INSERT T-SQL statements. (2) What you need to do, i.e. logic and your code attempt implementation of it in T-SQL. (3) Desired output, based on the sample data in the #1 above. (4) Your SQL Server version (SELECT @@version;). – Yitzhak Khabinsky Feb 19 '23 at 00:26
  • How about this? declare @XML xml = ' – fScheidell Feb 19 '23 at 15:35

1 Answers1

0

Please try the following solution.

It is using XQuery FLWOR expression to compose needed XML.

SQL

DECLARE @xml XML = 
N'<DWDocument>
    <FileInfos>
        <ImageInfos>
            <ImageInfo id="0,0,0" nPages="0">
                <FileInfo fileName="9b7b36ac-c705-49ba-bf91-a952bdb44576.eml" dwFileName="f0.eml" type="normal" length="0"/>
            </ImageInfo>
            <ImageInfo id="1,0,0" nPages="0">
                <FileInfo fileName="Response to Deficiency Letter.docx" dwFileName="f1.docx" type="normal" length="0"/>
            </ImageInfo>
        </ImageInfos>
    </FileInfos>
</DWDocument>';

DECLARE @ImageInfo_ID NVARCHAR(50) = '2,0,0';
DECLARE @ImageInfo_nPages NVARCHAR(50) = '0';

SET @xml = @xml.query('<DWDocument><FileInfos><ImageInfos>
{
    for $x in //DWDocument/FileInfos/ImageInfos
    return if ($x[position() lt last()]) then $x
        else $x, <ImageInfo id="{sql:variable("@ImageInfo_ID")}" nPages="{sql:variable("@ImageInfo_nPages")}"></ImageInfo>
}
</ImageInfos></FileInfos></DWDocument>');

-- test
SELECT @xml;

Output

<DWDocument>
  <FileInfos>
    <ImageInfos>
      <ImageInfos>
        <ImageInfo id="0,0,0" nPages="0">
          <FileInfo fileName="9b7b36ac-c705-49ba-bf91-a952bdb44576.eml" dwFileName="f0.eml" type="normal" length="0" />
        </ImageInfo>
        <ImageInfo id="1,0,0" nPages="0">
          <FileInfo fileName="Response to Deficiency Letter.docx" dwFileName="f1.docx" type="normal" length="0" />
        </ImageInfo>
      </ImageInfos>
      <ImageInfo id="2,0,0" nPages="0" />
    </ImageInfos>
  </FileInfos>
</DWDocument>
Yitzhak Khabinsky
  • 18,471
  • 2
  • 15
  • 21
  • I tried it and it works. However it is really a workaround and not an answer to the original question. I still dont know how to insert a variable without getting the error message: Msg 2225, Level 16, State 1, Line 22 XQuery [modify()]: A string literal was expected – fScheidell Feb 19 '23 at 23:51
  • There are many ways to achieve the same goal. XQuery FLWOR is one of them. – Yitzhak Khabinsky Feb 19 '23 at 23:56