How to replace attribute value of *all* matching elements with XQuery? - sql-server-2005

I'm trying without luck to create a modify() statement to change the value of an attribute in all elements that have that attribute value -- so far I can only get it to change the value in the first matched element. I created an example below of what I have so far, which I'm running in SQL Server 2005:
DECLARE #x XML
SELECT #x = '
<FootballApparel>
<Item Team="Phoenix Cardinals" Type="Hat" Cost="$14.99" />
<Item Team="Indianapolis Colts" Type="Hat" Cost="$14.99" />
<Item Team="Cincinnati Bengals" Type="Hat" Cost="$14.99" />
<Item Team="Phoenix Cardinals" Type="Shirt" Cost="$21.99" />
<Item Team="Indianapolis Colts" Type="Shirt" Cost="$21.99" />
<Item Team="Cincinnati Bengals" Type="Shirt" Cost="$21.99" />
</FootballApparel>
';
SET #x.modify('
replace value of
(/FootballApparel/Item[#Team="Phoenix Cardinals"]/#Team)[1]
with "Arizona Cardinals"
');
SELECT #x;
Running this gives the results below -- only the first instance of Phoenix Cardinals has been changed.
<FootballApparel>
<Item Team="Arizona Cardinals" Type="Hat" Cost="$14.99" />
<Item Team="Indianapolis Colts" Type="Hat" Cost="$14.99" />
<Item Team="Cincinnati Bengals" Type="Hat" Cost="$14.99" />
<Item Team="Phoenix Cardinals" Type="Shirt" Cost="$21.99" />
<Item Team="Indianapolis Colts" Type="Shirt" Cost="$21.99" />
<Item Team="Cincinnati Bengals" Type="Shirt" Cost="$21.99" />
</FootballApparel>
Can you please help me with the correct modify() statement to replace all instances?
Thanks!
Kevin

You're very close - what you need to do is loop (and there's no other way I know of to do it in this case) and repeatedly replace the values:
WHILE #x.exist('(/FootballApparel/Item[#Team=sql:variable("#oldTeamName")])[1]') = 1
SET #x.modify('
replace value of (
/FootballApparel/Item[#Team=sql:variable("#oldTeamName")]/#Team
)[1]
with sql:variable("#newTeamName")
');
That should do the trick.
Marc

Related

Can we remove image preview from ui fileuploader?

Is it possible to remove image preview from UI fileuploder component, without using file component?
here is my code=>
<field name="file">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">string</item>
<item name="source" xsi:type="string">TestGroup</item>
<item name="label" xsi:type="string" translate="true">File</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="formElement" xsi:type="string">fileUploader</item>
<item name="elementTmpl" xsi:type="string">ui/form/element/uploader/uploader</item>
<item name="previewTmpl" xsi:type="string">Vendor_Module/image-preview</item>
<item name="required" xsi:type="boolean">false</item>
<item name="sortOrder" xsi:type="number">40</item>
<item name="uploaderConfig" xsi:type="array">
<item name="url" xsi:type="url" path="controller/index/upload"/>
</item>
</argument>
</field>
tried by removing item name= elementTmpl and previewTmpl but not working
can anybody help me to disable the image preview for fileupload.
Thanks in Advance.
Remove the src of image every time you click:
$("#input1").click(function () {
$('#imagepreview1').attr('src','');
});

SELECT FROM XML MULTIPLE ELEMENTS SQL

I have a return of XML that I wish to select using SQL. I don't have a problem selecting from the XML when I specify the index for the element. This is the XML in question.
<root httpStatusCode="200">
<messages />
<succesfulResponses>
<item position="0">
<response dln="TESTDLN" ServiceVersion="1" hubServiceVersion="1.0.0.0" ProcessingDate="2017-11-20T10:42:20.579Z" hubProcessingDate="2017-11-20T10:41:16.5415151Z" httpStatusCode="200">
<licence status="FC" validFrom="2017-03-18" validTo="2024-10-31" directiveIndicator="4">
<entitlements>
<item code="A" validFrom="2006-04-07" validTo="2057-05-20" priorTo="false" type="P">
<restrictions />
</item>
<item code="AM" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions>
<item type="122" info="null" />
</restrictions>
</item>
<item code="B" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions />
</item>
<item code="BE" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
<restrictions />
</item>
<item code="F" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions />
</item>
<item code="G" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
<restrictions />
</item>
<item code="H" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
<restrictions />
</item>
<item code="K" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions />
</item>
<item code="Q" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions>
<item type="122" info="null" />
</restrictions>
</item>
</entitlements>
<endorsements />
</licence>
<messages />
</response>
</item>
</succesfulResponses>
<errorResponses />
</root>
The SQL I have written so far is as follows:
select
Rec.value('(#dln)[1]','char(50)'),
Rec.value('(licence/#status)[1]','char(2)'),
pd.value('(entitlements/item/#code)[1]','char(2)')
FROM #xmlData.nodes('//root/succesfulResponses/item/response') as x(Rec)
cross apply #xmlData.nodes('//root/succesfulResponses/item/response/licence') as i(pd)
This returns the obviously First Row code of 'A', however there can be multiple 'entitlements' and I don't ever know how many there could be 3 there could be 9.
I thought a Cross Apply would work but I can't seem to make that work either.
Any thoughts/help.
Try this - expand the XPath after the CROSS APPLY to include the entitlements/item part:
select
Rec.value('(#dln)[1]','char(50)'),
Rec.value('(licence/#status)[1]','char(2)'),
pd.value('#code', 'char(2)')
FROM
#xmlData.nodes('//root/succesfulResponses/item/response') as x(Rec)
cross apply
#xmlData.nodes('//root/succesfulResponses/item/response/licence/entitlements/item') as i(pd)
Returns:
The variant with OPENXML
DECLARE #idoc int, #doc varchar(MAX)
SET #doc='<root httpStatusCode="200">
<messages />
<succesfulResponses>
<item position="0">
<response dln="TESTDLN" ServiceVersion="1" hubServiceVersion="1.0.0.0" ProcessingDate="2017-11-20T10:42:20.579Z" hubProcessingDate="2017-11-20T10:41:16.5415151Z" httpStatusCode="200">
<licence status="FC" validFrom="2017-03-18" validTo="2024-10-31" directiveIndicator="4">
<entitlements>
<item code="A" validFrom="2006-04-07" validTo="2057-05-20" priorTo="false" type="P">
<restrictions />
</item>
<item code="AM" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions>
<item type="122" info="null" />
</restrictions>
</item>
<item code="B" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions />
</item>
<item code="BE" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
<restrictions />
</item>
<item code="F" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions />
</item>
<item code="G" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
<restrictions />
</item>
<item code="H" validFrom="2014-11-01" validTo="2057-05-20" priorTo="false" type="P">
<restrictions />
</item>
<item code="K" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions />
</item>
<item code="Q" validFrom="2014-10-21" validTo="2057-05-20" priorTo="false" type="F">
<restrictions>
<item type="122" info="null" />
</restrictions>
</item>
</entitlements>
<endorsements />
</licence>
<messages />
</response>
</item>
</succesfulResponses>
<errorResponses />
</root>'
EXEC sp_xml_preparedocument #idoc OUTPUT, #doc;
SELECT *
FROM OPENXML(#idoc,'/root/succesfulResponses/item/response/licence/entitlements/item',2)
WITH (
status varchar(10) '../../#status',
code varchar(10) './#code',
validFrom date './#validFrom'
);
EXEC sp_xml_removedocument #idoc;
GO

How to get value from XML in stored procedure?

Can you all help me for this problem?
I want to get value from following XML in sql stored procedure. I don't get vlaue if 'xsi:type="ActiveDirectoryItem"' is in tag 'anyType', and 'ActiveDirectoryItems' tag is also with URLs. How can i do to get only values?
<?xml version="1.0" encoding="utf-8" ?>
<ActiveDirectoryItems xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<Items>
<anyType xsi:type="ActiveDirectoryItem">
<FirstName />
<MiddleInitial />
<LastName />
<DisplayName>Migrate-group</DisplayName>
<UserPrincipalName />
<PostalAddress />
<ResidentialAddress />
<Title />
<HomePhone />
<OfficePhone />
<Mobile />
<Fax />
<Email>Migrate-group#gmail.com</Email>
<Url />
<AccountName>Migrate-group</AccountName>
<DistinguishedName />
<IsAccountActive>false</IsAccountActive>
<ManagedBy />
<Manager />
<CompareType>0</CompareType>
<Description />
<Department />
<Company />
<Type />
</anyType>
</Items>
<GlobalCatalog />
</ActiveDirectoryItems>
The format i want to get is as the following:
DisplayName Email Account Name
Migrate-group Migrate-group#gmail.com Migrate-group
you can use the value keyword
Example:
DECLARE #MyXml XML = '<Root><SomeData>100</SomeData></Root>'
DECLARE #Something INT
SELECT #Something = #MyXml.value('(//Root/SomeData)[1]', 'INT')

Using a CTE to insert a parsed XML

I'm developing a SQL Server 2012 stored procedure.
I want to parse this XML:
<Commissioning>
<Item ProductionId="115100" ItemId="100" ItemPackagingLevelId="1" ItemFlag="0" TimeStamp="2014-04-28T16:02:59.913" Username="" Source="PLS" />
<Item ProductionId="115101" ItemId="101" ItemPackagingLevelId="1" ItemFlag="0" TimeStamp="2014-04-28T16:03:00.113" Username="" Source="PLS" />
<Item ProductionId="115102" ItemId="102" ItemPackagingLevelId="1" ItemFlag="0" TimeStamp="2014-04-28T16:03:00.317" Username="" Source="PLS" />
<Item ProductionId="115103" ItemId="103" ItemPackagingLevelId="1" ItemFlag="0" TimeStamp="2014-04-28T16:03:00.517" Username="" Source="PLS" />
<Item ProductionId="115104" ItemId="104" ItemPackagingLevelId="1" ItemFlag="0" TimeStamp="2014-04-28T16:03:00.727" Username="" Source="PLS" />
</Commissioning>
And insert ItemId and ItemPackagingLevelId in a CTE because I want to do some calculations with that data.
How can I do it?
Like this...?
;with cte as (
select
x.n.value('./#ItemId','varchar(100)') as ItemID,
x.n.value('./#ItemPackagingLevelId','varchar(100)') as LevelID
from #x.nodes('/Commissioning/Item') x(n)
)
select * from cte

XPATH: Filtering (rather than selecting nodes), preserving hierarachy

Given the following XML (with many hierarchy levels), I need to return the nodes after filtering all nodes with Hide"True" attribute and a certain name. Note that hide could be at any hierarchy level:
<items>
<item id="1" >
<item id="2" />
<item id="3" />
<item id="4" hide="true"/>
</item>
<item id="5" hide="true">
<item id="6" >
<item id="7">
<item id="8" hide="true"/>
<item id="9"/>
</item>
</item>
</items>
I would need to get this back:
<items>
<item id="1"">
<item id="2" />
<item id="3" />
</item>
<item id="6" >
<item id="7">
<item id="9"/>
</item>
</item>
</items>
The 'filtered' XML is then assigned to a treeview, so I need to preserve the hierarchical nature of the nodes. I have tried: "items//item[#hide='false' or not(#hide)]", but this returns a flattened (as well as duplicative) data, repeating nodes at the lower level pushed up to the top level as follows. Is there a way to use Xpath to do what I want? I understand that I can Xslt the data first, then display it, but it just seems that there is got to be an easier way. I am using c#/.net4.0 MSXML
<items>
<item id="1"">
<item id="2" />
<item id="3" />
</item>
<item id="6" >
<item id="7">
<item id="9"/>
</item>
</item>
<item id="2" />
<item id="3" />
<item id="7">
<item id="9"/>
</item>
<item id="9"/>
</items>