XSL: create an Array from a Delimited String - arrays

I have a string name "string Variable" = 'hello, hello, good Evening, good evening'.
I want to create an array on which I can do a foreach with the values divided by commas.
tnks

XSLT and XPath don't have an array data type unless you happen to use XPath 3.1 with XSLT 3. However in XSLT and XPath since version 2 there is a tokenize function you can use with e.g. tokenize('hello, hello, good Evening, good evening', ',\s*') to get a sequence of strings you can then process like any other sequence, for instance with a for-each.

Related

SQL Server: STRING_SPLIT() result in a computed column

I couldn't find good documentation on this, but I have a table that has a long string as one of it's columns. Here's some example data of what it looks like:
Hello:Goodbye:Apple:Orange
Example:Seagull:Cake:Chocolate
I would like to create a new computed column using the STRING_SPLIT() function to return the third value in the string table.
Result #1: "Apple"
Result #2: "Cake"
What is the proper syntax to achieve this?
At this time your answer is not possible.
The output rows might be in any order. The order is not guaranteed to
match the order of the substrings in the input string.
STRING_SPLIT reference
There is no way to guarantee which item was the third item in the list using string_split and the order may change without warning.
If you're willing to build your own, I'd recommend reading up on the work done by
Brent Ozar and Jeff Moden.
You shouldn't be storing data like that in the first place. This points to a potentially serious database design problem. BUT you could convert this string into JSON by replacing : with ",", surround it with [" and "] and retrieve the third array element , eg :
declare #value nvarchar(200)='Example:Seagull:Cake:Chocolate'
select json_value('["' + replace(#value,':','","' )+ '"]','$[2]')
The string manipulations convert the string value to :
["Example","Seagull","Cake","Chocolate"]
After that, JSON_VALUE parses the JSON string and retrieves the 3rd item in the array using a JSON PATH expression.
Needless to say, this will be slow and can't take advantage of indexing. If those values are meant to be read or written individually, they should be stored in separate columns. They'll probably take less space than one long string.
If you have a lot of optional fields but only a subset contain values at any time, you could use sparse columns. This way you could have thousands of rows, only a few of which would contain data at any time

Complex string match SPSS (v20)

I got a problem I cant figure out using SPSS (v20).
There is a master list with 10.000 strings. Think of it as an array like so:
['Sao Paolo S.P.', 'IDE MUNICH', '1_New YORK', 'BabylonX', ...]
I have a dataset with a variable, that contains strings similar to the beforementioned array, but that are not the exact same ones.
Like so:
What I need to do is: check if OldString (from the dataset) is part of any of the strings in the master array.
Obviously 123 Babylon (from the dataset) will be related to BabylonX (from the array).
Obviously 1234 Sao Paolo S (from the dataset) will be related to Sao Paolo S.P. (from the array).
and so on...
If a match is detected, then the string from the (master)array should be filled in in a new variable NewString.
Is there any way to achieve that? Using VBA, Perl, PHP this is dead easy, but using SPSS I got no clue how to combine those steps.
The following syntax is a possible way to do loop the match comparison using char.index.
*First I'm turning your master list into a dataset -
this can be done differently depending how the data is
stored right now. In this example I just copy-pasted
from your post into the syntax.
data list free/masterstring (a20).
begin data
'Sao Paolo S.P.', 'IDE MUNICH', '1_New YORK', 'BabylonX'
end data.
*now I create a new syntax with a comparison command for each string in the list.
cd "c:\your path".
string cmd (a100).
compute cmd=concat("if char.index('",lower(rtrim(masterstring)),"',
lower(rtrim(mystring)))>0 matchedstr='",rtrim(masterstring),"'.").
write out="check strings.sps"/cmd.
* the syntax is ready, at this point you will go back to your original dataset.
For the example I'm creating a small example dataset.
data list free/mystring (a20).
begin data
"123 Babylon" "babylon" "Sao Paolo" "1234 Sao Paolo S"
end data.
*now we can run the syntax created earlier on the present dataset.
string matchedstr (a50).
insert file="check strings.sps".
exe.
What you should see in the result is that "babylon" was recognized as part of "BabylonX" (the command equalizes lower/upper cases) and therefore "BabylonX" appears in the matchedstring. The same for "Sao Paolo" and "Sao Paolo S.P.".
Note: if mystring matches more than one string in the list, the present syntax will only capture the last match.

Returning a concatenated string of property values for multiple nodes using XPath

I'm working on a C project using libxml2.
I keep an XML document of the following form:
<?xml version="1.0">
<rootnode version="1.0">
<rootchild attribute1="a" attribute2="12345678" />
<rootchild attribute1="b" attribute2="ABCDEFGH" />
</rootnode>
I'd like to get a string of concatenated attribute2 values with a comma as delimiter, so for the example above the string would be: "12345678,ABCDEFGH"
I'd like to get as close to that string as possible using XPath. So far the best I can do is get the nodes using the following expression: /rootnode/rootchild/attribute::attribute2
Wrapping the above with a string() seems to return only the first attribute2 value.
Is it possible to get more than one attribute2 value using a string() function?
Is it possible to concatenate several values separated by a delimiter using XPath?
With XPath 2.0 you could use /rootnode/rootchild/attribute::attribute2/string() to get a sequence of string values or string-join(/rootnode/rootchild/attribute::attribute2, ',') to a single string but libxml2 does only support XPath 1.0 so you will need to evaluate /rootnode/rootchild/attribute::attribute2 and then take the string value of each attribute and concatenate the values in your host language (C).

SQL Server - how to insert a substring?

I have a string like
`...<..../><... id='someID' .../><...../>....`
(the total length of that string is more than 15k chars, it's an XML form definition)
Inside of that string I have the someID value. I want to put after the element containing that value a new string:
...<..../><... id='someID' .../><my_new_string><...../>....
I tried to split that long string basing on the someID value, but that approach is too slow. How can I achieve that on the other way ?
Or maybe is it possible to select the substring <... id='someID' .../> ?
SQL server can work with XML. You do not need to use substring.
A simular problem was solved on this page: xml.modify
Have you tried using Replace? For example:
REPLACE(yourString, yourPattern, yourPattern + newString);
Using your example, it would look something like:
REPLACE('...<..../><... id='someID' .../><...../>....',
'<... id=''someID'' .../>',
'<... id=''someID'' .../><my_new_string>');
Please notice I escaped the ' characters around "someID".
Best regards.
It isn't clear what data type your string is: xml or (n)varchar? For xml, you can use the various data type methods; for (n)varchar the STUFF() function inserts one string into another string.

XQuery to get list of attributes

If I have several Section elements in an XML document, what XQuery do I use to get a list of all the name values?
<Section name="New Clients" filePath="XNEWCUST.TXT" skipSection="False">
In XPath 2.0 (which is a subset of XQuery) one would use the following expression to get a sequence of all string values of the "name" attributes of the "Section" elements:
for $attr in //Section/#name
return string($attr)
Do note that using the "//" abbreviation is typically a bad practice as this may require a whole (subtree) to be traversed. In any case where the structure of the document is known a more specific XPath expression (such as one using specific location steps) should be preferred.
//Section/#name
or
//Section/#name/string(.)
for the string values
/Section/#name

Resources