Add children to existing node using R XML - r

I have the following XML file test.graphml that I am trying to manipulate using the XML package in R.
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<graph id="G" edgedefault="directed">
<node id="n0"/>
<node id="n1"/>
<node id="n2"/>
<node id="n3"/>
<node id="n4"/>
<edge source="n0" target="n1"/>
<edge source="n0" target="n2"/>
<edge source="n2" target="n3"/>
<edge source="n1" target="n3"/>
<edge source="n3" target="n4"/>
</graph>
</graphml>
I would like to nest nodes n0, n1, n2, and n3 into a new graph node as shown below.
<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<graph id="G" edgedefault="directed">
<graph id="g1">
<node id="n0"/>
<node id="n1"/>
<node id="n2"/>
<node id="n3"/>
</graph>
<node id="n4"/>
<edge source="n0" target="n1"/>
<edge source="n0" target="n2"/>
<edge source="n2" target="n3"/>
<edge source="n1" target="n3"/>
<edge source="n3" target="n4"/>
</graph>
</graphml>
The code I have written has unknowns and errors that I am unable to resolve due to lack of experience with XML processing. I would greatly appreciate some pointers to that will help me proceed.
library(XML)
# Read file
x <- xmlParse("test.graphml")
ns <- c(graphml ="http://graphml.graphdrawing.org/xmlns")
# Create new graph node
ng <- xmlNode("graph", attrs = c("id" = "g1"))
# Add n0-n3 as children of new graph node
n0_n1_n2_n3 <- getNodeSet(x,"//graphml:node[#id = 'n0' or #id='n1' or #id='n2' or #id='n3']", namespaces = ns)
ng <- append.xmlNode(ng, n0_n1_n2_n3)
# Get only graph node
g <- getNodeSet(x,"//graphml:graph", namespaces = ns)
# Remove nodes n0-n3 from the only graph node
# How I do this?
# This did not work: removeNodes(g, n0_n1_n2_n3)
# Add new graph node as child of only graph node
g <- append.xmlNode(g, ng)
#! Error message:
Error in UseMethod("append") :
no applicable method for 'append' applied to an object of class "XMLNodeSet"

Consider XSLT, the special-purpose language to transform XML files. Since you require modification of the XML (adding parent node in a select group of children) and have to navigate through an undeclared namespace prefix (xmlns="http://graphml.graphdrawing.org/xmlns"), XSLT is an optimal solution.
However, to date R does not have a fully compliant XSL module to run XSLT 1.0 scripts like other general purpose languages (Java, PHP, Python). Nonetheless, R can call external programs (including aforementioned languages), or dedicated XSLT processors (Xalan, Saxon), or call command line interpreters including PowerShell and terminal's xsltproc using system(). Below are latter solutions.
XSLT (save as .xsl, to be referenced in R script)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://graphml.graphdrawing.org/xmlns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="doc:graphml">
<xsl:copy>
<xsl:copy-of select="document('')/*/#xsi:schemaLocation"/>
<xsl:apply-templates select="doc:graph"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc:graph">
<xsl:element name="{local-name()}" namespace="http://graphml.graphdrawing.org/xmlns">
<xsl:apply-templates select="#*"/>
<xsl:element name="graph" namespace="http://graphml.graphdrawing.org/xmlns">
<xsl:attribute name="id">g1</xsl:attribute>
<xsl:apply-templates select="doc:node[position() < 5]"/>
</xsl:element>
<xsl:apply-templates select="doc:node[#id='n4']|doc:edge"/>
</xsl:element>
</xsl:template>
<xsl:template match="doc:graph/#*">
<xsl:attribute name="{local-name()}"><xsl:value-of select="."/></xsl:attribute>
</xsl:template>
<xsl:template match="doc:node|doc:edge">
<xsl:element name="{local-name()}" namespace="http://graphml.graphdrawing.org/xmlns">
<xsl:attribute name="{local-name(#*)}"><xsl:value-of select="#*"/></xsl:attribute>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
PowerShell script (for Windows PC users, save as XMLTransform.ps1)
param ($xml, $xsl, $output)
if (-not $xml -or -not $xsl -or -not $output) {
Write-Host "& .\xslt.ps1 [-xml] xml-input [-xsl] xsl-input [-output] transform-output"
exit;
}
trap [Exception]{
Write-Host $_.Exception;
}
$xslt = New-Object System.Xml.Xsl.XslCompiledTransform;
$xslt.Load($xsl);
$xslt.Transform($xml, $output);
Write-Host "generated" $output;
R Script (calling command line operations)
library(XML)
# WINDOWS USERS
ps <- '"C:\\Path\\To\\XMLTransform.ps1"' # POWER SHELL SCRIPT
input <- '"C:\\Path\\To\\Input.xml"' # XML SOURCE
xsl <- '"C:\\Path\\To\\XSLTScript.xsl"' # XSLT SCRIPT
output <- '"C:\\Path\\To\\Output.xml"' # BLANK, EMPTY FILE PATH TO BE CREATED
system(paste('Powershell.exe -executionpolicy remotesigned -File',
ps, input, xsl, output)) # NOTE SECURITY BYPASS ARGS
doc <- xmlParse("C:\\Path\\To\\Output.xml")
# UNIX (MAC/LINUX) USERS
system("xsltproc /path/to/XSLTScript.xsl /path/to/input.xml -o /path/to/output.xml")
doc <- xmlParse("/path/to/output.xml")
print(doc)
# <?xml version="1.0" encoding="utf-8"?>
# <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
# <graph id="G" edgedefault="directed">
# <graph id="g1">
# <node id="n0"/>
# <node id="n1"/>
# <node id="n2"/>
# <node id="n3"/>
# </graph>
# <node id="n4"/>
# <edge source="n0"/>
# <edge source="n0"/>
# <edge source="n2"/>
# <edge source="n1"/>
# <edge source="n3"/>
# </graph>
# </graphml>

Related

WSO2 : Transforming response xml

I would like to turn this xml response into something more easily readable.
<?xml version="1.0" encoding="ISO-8859-1"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/>
<soap:Body>
<executeResponse xmlns="urn:GCE">
<BusinessViewServiceexecuteOut xmlns="http://www.generix.fr/technicalframework/businesscomponent/applicationmodule/common" xmlns:ns2="http://www.generixgroup.com/processus/configuration/scheduler" xmlns:ns3="http://www.generix.fr/technicalframework/business/service/common">
<xmlpres><?xml version = '1.0' encoding = 'UTF-8'?> <VueTable type="View" name="Table" habctr="true" total_business_row="2" nbline="400" confNbline="400" numpage="1" nbpage="1">
<JTblView name="JTblView" type="ViewObject" maxfetchsize="999" maxfetchsizeexceeded="false">
<JTblViewRow current="true" type="ViewRow" index="1" business_row_index="1">
<Cletbl precision="6" type="VARCHAR" pk="true">
<business_data>N</business_data>
</Cletbl>
<Codtbl precision="6" type="VARCHAR" pk="true">
<business_data>001</business_data>
</Codtbl>
<Lib1 precision="30" type="VARCHAR">
<business_data>Non</business_data>
</Lib1>
<Lib2 precision="30" type="VARCHAR">
<business_data/>
</Lib2>
<Lir precision="10" type="VARCHAR">
<business_data>Non</business_data>
</Lir>
</JTblViewRow>
<JTblViewRow type="ViewRow" index="2" business_row_index="2">
<Cletbl precision="6" type="VARCHAR" pk="true">
<business_data>O</business_data>
</Cletbl>
<Codtbl precision="6" type="VARCHAR" pk="true">
<business_data>001</business_data>
</Codtbl>
<Lib1 precision="30" type="VARCHAR">
<business_data>Oui</business_data>
</Lib1>
<Lib2 precision="30" type="VARCHAR">
<business_data/>
</Lib2>
<Lir precision="10" type="VARCHAR">
<business_data>Oui</business_data>
</Lir>
</JTblViewRow>
</JTblView>
</VueTable></xmlpres>
</BusinessViewServiceexecuteOut>
</executeResponse>
</soap:Body></soap:Envelope>
At least if I could extract what's in the value of "xmlpres", the better I could do:
<table><row><code></code><libelle></libelle/></row></table>
To then turn it into a json response but I can't see ... I just get all the output or in json stream but with everything , which is not usable.
Create an out-mediation sequence with the following content and attach it to the respective API and try out the scenario. This is to extract the xmlpres content and send that as the response to the client
<?xml version="1.0" encoding="UTF-8"?>
<sequence xmlns="http://ws.apache.org/ns/synapse" name="out-sequence">
<!-- extract the xmlpres content and store as OM element -->
<property name="XMLBody"
expression="$body//soap:Body//generic:xmlpres"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:gce="urn:GCE"
xmlns:generic="http://www.generix.fr/technicalframework/businesscomponent/applicationmodule/common" type="OM" />
<!-- pass the extracted property as response body -->
<enrich>
<source type="property" property="XMLBody" />
<target type="body" />
</enrich>
</sequence>
Hope this helps you to extract and send the response accordingly.

XQuery error: Filtering with variable returning empty result

I try to run the following XQuery:
let $d := doc("ferry.xml")
let $x := $d/ferry/trips/trip[#depart='08:00' and start='Stockholm']/captain[#crew]
return $d/ferry/crews/crew[#crewID=$x]/name
And get an empty result.
I would like to get the value in <name> where <crew crewID="JI"> (=Jill).
I can see that $x includes <captain crew="JI"/> and when I run
return $d/ferry/crews/crew[#crewID='JI']/name
I get the expected result.
How can I make the return function read the variable correctly? Here is the XML file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ferry>
<ships>
<ship shipID="SKHM">
<name>Skeppsholm</name>
</ship>
<ship shipID="PERL">
<name>Pearl</name>
<cars>40</cars>
</ship>
<ship shipID="REVG">
<name>Revenge></name>
<length>50</length>
</ship>
</ships>
<crews>
<crew crewID="JO">
<name>Jack</name>
<job>service</job>
<job>deckhand</job>
</crew>
<crew crewID="JI">
<name>Jill</name>
<job>captain</job>
<job>firstmate</job>
</crew>
<crew crewID="HA">
<name>Harry</name>
<job>deckhand</job>
</crew>
</crews>
<trips>
<trip date="20171020" depart="08:00">
<start>Stockholm</start>
<end>Vaxholm</end>
<captain crew="JI" />
<service crew="JO" />
</trip>
<trip date="20171130" depart="10:00">
<start>Nacka</start>
<end>Gustavberg</end>
<captain crew="JI" />
<deckhand crew="HA" />
<service crew="JA" />
</trip>
</trips>
</ferry>
Try changing
let $x := $d/ferry/trips/trip[#depart='08:00' and start='Stockholm']/captain[#crew]
to
let $x := $d/ferry/trips/trip[#depart='08:00' and start='Stockholm']/captain/#crew
You need $x to be just the value of the crew attribute; currently it returns the whole element <captain crew="JI"/>.

XML to list and back to XML

Situation: "Software" to R and back to "Software". The only interface for "Software" is xml.
In R, I need to make a few changes in the file so i convert it to a list and make some changes.
library(XML)
myFile = xmlParse("myXML")
xml_data <- xmlToList(myFile)
xml_data$timetable$train$.attrs[6] = "HelloNewWorld"
Now i need to convert this list "xml_data" it back to xml.
I found some functions like this:
function(item, tag) {
# just a textnode, or empty node with attributes
if(typeof(item) != 'list') {
if (length(item) > 1) {
xml <- xmlNode(tag)
for (name in names(item)) {
xmlAttrs(xml)[[name]] <- item[[name]]
}
return(xml)
} else {
return(xmlNode(tag, item))
}
}
# create the node
if (identical(names(item), c("text", ".attrs"))) {
# special case a node with text and attributes
xml <- xmlNode(tag, item[['text']])
} else {
# node with child nodes
xml <- xmlNode(tag)
for(i in 1:length(item)) {
if (names(item)[i] != ".attrs") {
xml <- append.xmlNode(xml, listToXml(item[[i]], names(item)[i]))
}
}
}
# add attributes to node
attrs <- item[['.attrs']]
for (name in names(attrs)) {
xmlAttrs(xml)[[name]] <- attrs[[name]]
}
return(xml)
}
But this doesnt work...
Any help or hints appreciated!
Thanks!
In the linked picture you can see the current xml-file. Highlighted in yellow the values that I need to change.
Link:
https://i.stack.imgur.com/remzj.png
Consider XSLT, the special-purpose language designed to transform XML files. No need to rewrite the entire tree in R. Using its xslt package (available on CRAN-R), extension of xml2, you can transform an input source and write output to screen or file.
Using the Identity Transform to copy document as is, below XSLT then rewrites one of the attributes in <train> tag, #source, similar to your above code attempt but with sixth attribute.
XML (sample input from railIML Wiki page)
<?xml version="1.0" encoding="UTF-8"?>
<railml xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xsi:noNamespaceSchemaLocation="timetable.xsd">
<timetable version="1.1">
<train trainID="RX 100.2" type="planned" source="opentrack">
<timetableentries>
<entry posID="ZU" departure="06:08:00" type="begin"/>
<entry posID="ZWI" departure="06:10:30" type="pass"/>
<entry posID="ZOER" arrival="06:16:00" departure="06:17:00" minStopTime="9" type="stop"/>
<entry posID="WS" departure="06:21:00" type="pass"/>
<entry posID="DUE" departure="06:23:00" type="pass"/>
<entry posID="SCW" departure="06:27:00" type="pass"/>
<entry posID="NAE" departure="06:29:00" type="pass"/>
<entry posID="UST" arrival="06:34:30" type="stop"/>
</timetableentries>
</train>
</timetable>
</railml>
XSLT (save as .xsl file, rewrites the #source attribute)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="#source">
<xsl:attribute name="source">HelloNewWorld</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
R
library(xslt)
doc <- read_xml("/path/to/Input.xml", package = "xslt")
style <- read_xml("/path/to/XLSTScript.xsl", package = "xslt")
new_xml <- xml_xslt(doc, style)
# OUTPUT TO SCREEN
cat(as.character(new_xml))
# OUTPUT TO FILE
write_xml(new_xml, "/path/to/Output.xml")
Output
<?xml version="1.0" encoding="UTF-8"?>
<railml xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance" xsi:noNamespaceSchemaLocation="timetable.xsd">
<timetable version="1.1">
<train trainID="RX 100.2" type="planned" source="HelloNewWorld">
<timetableentries>
<entry posID="ZU" departure="06:08:00" type="begin"/>
<entry posID="ZWI" departure="06:10:30" type="pass"/>
<entry posID="ZOER" arrival="06:16:00" departure="06:17:00" minStopTime="9" type="stop"/>
<entry posID="WS" departure="06:21:00" type="pass"/>
<entry posID="DUE" departure="06:23:00" type="pass"/>
<entry posID="SCW" departure="06:27:00" type="pass"/>
<entry posID="NAE" departure="06:29:00" type="pass"/>
<entry posID="UST" arrival="06:34:30" type="stop"/>
</timetableentries>
</train>
</timetable>
</railml>
I found it hard to apply many of the answers listed here so I wonder if this set of simple Java XML XPathHelper Unities may help others. You can find the source code here. I didn't write it all myself but adapted code I found, so I can't take all the credit but it works and it is compact and hope it helps others.
String xmlPayLoad = readFileAsString(payLoadPath + "/payLoad.xml");
TreeMap<String, String> header = new TreeMap<String, String>();
XPathHelperCommon xph = new XPathHelperCommon();
header = xph.findMultipleXMLItems(xmlPayLoad, "//header/*");
header.put("type", "newProcess");
xmlPayLoad = xph.modifyMultipleXMLItems(xmlPayLoad, "//header/*", header);
The primative XML header could be something like this:
<header>
<type>process</type>
<ruleBaseVersion>0</ruleBaseVersion>
<ruleBaseCommitment>0</ruleBaseCommitment>
<sequenceId>0</sequenceId>
<priortiseSID>0</priortiseSID>
<monitorIncomingEvents>0</monitorIncomingEvents>
<activityCount>0</activityCount>
<taskElapsedTime>0</taskElapsedTime>
<processStartTime>0</processStartTime>
<processElapsedTime>0</processElapsedTime>
<eventElapsedTime>0</eventElapsedTime>
<status>0</status>
</header>

Formatting date time using XSLT

I have a requirement in which I have to format the date value in the incoming request. I am able to extract the value however it is not getting properly formatted.
Below is the Input request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<Invoice Version="3.0">
<Header>
<ThisDocumentIdentifier>
<DocumentIdentifier>0000001007128564</DocumentIdentifier>
</ThisDocumentIdentifier>
<ThisDocumentDateTime>
<DateTime DateTimeQualifier="On">20140429T031659Z</DateTime>
</ThisDocumentDateTime>
</Header>
</Invoice>
</soapenv:Body>
</soapenv:Envelope>
The Date value is 20140429T031659Z
Output needed 2014-04-29T03:16:59Z
Below is the code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:dp="http://www.datapower.com/extensions">
<xsl:template match="*[local-name()='DateTime']">
<xsl:variable name="FormatDatetime">
<xsl:value-of select="concat(substring(., 1, 4), '-', substring(., 5, 2), '-', substring(., 7, 2),substring(.,9,2),':',substring(.,11,2),':',substring(.,13,2),'Z')"/>
</xsl:variable>
<xsl:message dp:priority="debug"> Formatted date= <xsl:value-of select="$FormatDatetime"/>
</xsl:message>
</xsl:template>
</xsl:stylesheet>
This is the output I am getting
2014-04-29T0:31:65Z
For some reason one of the number is getting removed and I am not sure why?
Can anyone please advise where I am doing it wrong?
I have added the 'T' as well.
<xsl:value-of select="concat(substring(., 1, 4), '-', substring(., 5, 2), '-', substring(., 7, 2),'T',substring(.,9,2),':',substring(.,11,2),':',substring(.,13,2),'Z')"/>
Got the output as
2014-04-29TT0:31:65Z
This is the updated working code thank to panhandel.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:dp="http://www.datapower.com/extensions">
<xsl:template match="*[local-name()='DateTime']">
<xsl:variable name="FormatDatetime">
<xsl:value-of select="concat(substring(., 1, 4), '-', substring(., 5, 2), '-', substring(., 7, 2),substring(.,9,3),':',substring(.,11,2),':',substring(.,13,2),'Z')"/>
</xsl:variable>
<xsl:message dp:priority="debug"> Formatted date= <xsl:value-of select="$FormatDatetime"/>
</xsl:message>
</xsl:template>
</xsl:stylesheet>
Looks like you shorted the T03 part by one character by using substring(.,9,2).
It should be substring(.,9,3)

XSLT : Cannot convert the operand to 'Result tree fragment'

I work on an xslt stylesheet, and I should receive as parameter two additional XML. I get an error when I use the node-set() method (from namespace ms, microsoft). The contents of the XML is correct. The parameters are send with classic ASP.
Here's the header and the call in xslt:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
...
<xsl:param name="xmlPlanning"></xsl:param>
<xsl:variable name="myXml" select="ms:node-set($xmlPlanning)"></xsl:variable>
<xsl:value-of select="ms:node-set($xmlPlanning)/*"/>
Here's the stack trace of the error:
[XsltException: Impossible de convertir l'opérande en 'fragment de l'arborescence résultat'.]
System.Xml.Xsl.XsltOld.XsltFunctionImpl.ToNavigator(Object argument) +380943
System.Xml.Xsl.XsltOld.FuncNodeSet.Invoke(XsltContext xsltContext, Object[] args, XPathNavigator docContext) +33
MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator) +292
[XPathException: Échec de la fonction 'ms:node-set()'.]
MS.Internal.Xml.XPath.FunctionQuery.Evaluate(XPathNodeIterator nodeIterator) +347
System.Xml.Xsl.XsltOld.Processor.RunQuery(ActionFrame context, Int32 key) +24
System.Xml.Xsl.XsltOld.VariableAction.Execute(Processor processor, ActionFrame frame) +200
System.Xml.Xsl.XsltOld.ActionFrame.Execute(Processor processor) +20
System.Xml.Xsl.XsltOld.Processor.Execute() +82
System.Xml.Xsl.XsltOld.Processor.Execute(TextWriter writer) +96
System.Xml.Xsl.XslTransform.Transform(XPathNavigator input, XsltArgumentList args, TextWriter output, XmlResolver resolver) +68
System.Xml.Xsl.XslTransform.Transform(IXPathNavigable input, XsltArgumentList args, TextWriter output, XmlResolver resolver) +43
System.Web.UI.WebControls.Xml.Render(HtmlTextWriter output) +132
And here's the beginning of the xml I receive in parameter :
<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfGenerationPlanningDesign xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://webservices.secureholiday.net/">
<GenerationPlanningDesign>
What could be my problem ?
In case the parameter you are passing is already a true nodeset (XPath navigator or XPathNodeIterator in .NET or IXMLDOMNodeList for MSXML), you don't need and must not use the ms:node-set() extension function. Simply remove the call to ms:nodeset().
In case it is a string that represents XML -- well it shouldn't! Parse this string to one of the allowable parameter types for a nodeset and only then invoke the transformation -- using the true node-set.
node-set() operates on Result Document Fragments (RDFs) only, but you give it a string, which is something entirely different (even if the string contents looks like XML).
What you must do is parse the string into XML. You can use an extension script for that. The following worked for me (tested with msxsl.exe on the command line), but if you don't want to use JScript you can use C# or any other supported language to do the same.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:script="urn:my-scripts"
exclude-result-prefixes="ms script"
>
<ms:script language="JScript" implements-prefix="script">
<![CDATA[
function stringToXml(str) {
var xml = new ActiveXObject("MSXML2.DOMDocument.4.0");
xml.async = false;
xml.loadXML(str);
return xml;
}
]]>
</ms:script>
<xsl:param name="xmlPlanning"></xsl:param>
<xsl:variable name="myXml" select="script:stringToXml(string($xmlPlanning))" />
<xsl:template match="/">
<xsl:value-of select="$myXml/*" /><!-- whatever -->
</xsl:template>
</xsl:stylesheet>
As Dimitre said you can use ms:node-set but you must use node()
<xsl:variable name="yourVariable">
<xsl:copy-of select="/foo/bar/something/node()"/>
</xsl:variable>
<xsl:value-of select="ms:node-set($yourVariable)/theOtherElement"/>

Resources