Reputation: 63
I'm trying to modify a third party xml so that all the elements have Id's from T-SQL.
This is the original xml (section):
<Tables>
<Table Type="LineItem">
<TableRow>
<Field Name="LI_NominalCode" Type="wd_lit_nominalcode">244234</Field>
<Field Name="LI_NominalDesc" Type="lit_nominaldesc">RENT RECEIVABLE - INTERNAL</Field>
<Field Name="LI_Account" Type="lit_wd_account" />
<Field Name="LI_AccountDesc" Type="lit_wd_accountdesc" />
<Field Name="LI_SecondAccount" Type="lit_wd_2ndaccount" />
<Field Name="LI_SecondAccountDesc" Type="lit_wd_2ndaccountdesc" />
<Field Name="LI_NetValue" Type="lit_vatexcludedamount">4522.89</Field>
<Field Name="LI_EnergyUsage" Type="wd_energyusage">56666</Field>
<Field Name="LI_EnergyType" Type="wd_energytype">ELECTRICITY</Field>
</TableRow>
<TableRow>
<Field Name="LI_NominalCode" Type="wd_lit_nominalcode">150021</Field>
<Field Name="LI_NominalDesc" Type="lit_nominaldesc">Rent Building 1</Field>
<Field Name="LI_Account" Type="lit_wd_account" />
<Field Name="LI_AccountDesc" Type="lit_wd_accountdesc" />
<Field Name="LI_SecondAccount" Type="lit_wd_2ndaccount" />
<Field Name="LI_SecondAccountDesc" Type="lit_wd_2ndaccountdesc" />
<Field Name="LI_NetValue" Type="lit_vatexcludedamount">456.37</Field>
<Field Name="LI_EnergyUsage" Type="wd_energyusage">2805.00</Field>
<Field Name="LI_EnergyType" Type="wd_energytype">ELECTRICITY</Field>
</TableRow>
<TableRow>
<Field Name="LI_NominalCode" Type="wd_lit_nominalcode">2342341</Field>
<Field Name="LI_NominalDesc" Type="lit_nominaldesc">Rent Building 2</Field>
<Field Name="LI_Account" Type="lit_wd_account" />
<Field Name="LI_AccountDesc" Type="lit_wd_accountdesc" />
<Field Name="LI_SecondAccount" Type="lit_wd_2ndaccount" />
<Field Name="LI_SecondAccountDesc" Type="lit_wd_2ndaccountdesc" />
<Field Name="LI_NetValue" Type="lit_vatexcludedamount">355</Field>
<Field Name="LI_EnergyUsage" Type="wd_energyusage">6900</Field>
<Field Name="LI_EnergyType" Type="wd_energytype">ELECTRICITY</Field>
</TableRow>
</Table>
<Table Type="BankAccountTable" />
<Table Type="VATTable" />
</Tables>
As you can see, the <Table>
elements don't have Id's, so later in the process is difficult to identify them.
I'd like to create a loop to go through all the <Table>
elements and execute a snippet like this:
set @xml.modify('
insert attribute ID {sql:variable("@idString")}
into (/Documents/Document/Invoice/Tables/Table[@Type="LineItem"]/TableRow)[sql:variable("@id")]')
The problem lies on the last sql variable, the error is:
XQuery [modify()]: Only 'http://www.w3.org/2001/XMLSchema#decimal?', 'http://www.w3.org/2001/XMLSchema#boolean?' or 'node()*' expressions allowed as predicates, found 'xs:string ?'
This works fine, but I dont want to change always the same row (number 1).
set @xml.modify('
insert attribute ID {sql:variable("@idString")}
into (/Documents/Document/Invoice/Tables/Table[@Type="LineItem"]/TableRow)[1]')
By the way, if I use an int variable instead of a string as such:
set @xml.modify('insert attribute ID {sql:variable("@idString")}
into (/Documents/Document/Invoice/Tables/Table[@Type="LineItem"]/TableRow)[sql:variable("@idInt")]')`
I get another error:
XQuery [modify()]: The target of 'insert' must be a single node, found 'element(TableRow,xdt:untyped) *
Upvotes: 5
Views: 1120
Reputation: 63
The only thing I can come up with is a stored procedure with all the possible rows (heard somebody flushing the toilet?)
if (@row = 1)
BEGIN
set @xml.modify('
insert attribute ID {sql:variable("@id")}
into (/Documents[1]/Document[1]/Invoice[1]/Tables[1]/Table[@Type="LineItem"][1]/TableRow)[1]
')
END
ELSE if (@row = 2)
BEGIN
set @xml.modify('
insert attribute ID {sql:variable("@id")}
into (/Documents[1]/Document[1]/Invoice[1]/Tables[1]/Table[@Type="LineItem"][1]/TableRow)[2]
')
END
ELSE if (@row = 3)
BEGIN
set @xml.modify('
insert attribute ID {sql:variable("@id")}
into (/Documents[1]/Document[1]/Invoice[1]/Tables[1]/Table[@Type="LineItem"][1]/TableRow)[3]
')
END
Hopefully won't be more than 200...
Upvotes: 1
Reputation: 138990
You can compare the variable @id
to function position()
.
declare @id int
declare @RowCount int
select @RowCount = @xml.value('count(/Tables/Table[@Type="LineItem"]/TableRow)', 'int')
set @id = 1
while @id <= @RowCount
begin
set @xml.modify('
insert attribute ID {sql:variable("@id")}
into (/Tables/Table[@Type="LineItem"]/TableRow[position()=sql:variable("@id")])[1]')
set @id = @id + 1
end
Upvotes: 2