The following statement will create a new file on the graph server:
graph.io(IoCore.graphml()).writer().normalize(true).create().writeGraph(new FileOutputStream("export.graphml"), graph)
I want to use a different OutputStream to see the output directly in my gremlin client. I have tried DataOutputStream() but got a NullPointerException. How would I get the response from writeGraph()?
I originally read this question as wanting to know how to create a remote OutputStream to write from the server back to some local file on the client, which likely has some solution but I'm not sure what the answer is to that. As I happen to look at this question again though the bounty notes that you are interested in "Export of full tinkerpop graph to console" in which case perhaps a different approach will satisfy.
I would simply construct a GraphMLWriter directly using its Builder and then write to a byte[] and return that as a String:
baos = new ByteArrayOutputStream()
graph.io(IoCore.graphml()).writer().normalize(true).create().writeGraph(baos, graph)
baos.toByteArray()
Here is the full console session though I've elided some of the graphml to help with readability:
gremlin> :remote connect tinkerpop.server conf/remote-objects.yaml session
==>Configured localhost/127.0.0.1:8182-[df3107c1-b25b-4f1c-a1f3-552353e9023d]
gremlin> :remote console
==>All scripts will now be sent to Gremlin Server - [localhost/127.0.0.1:8182]-[df3107c1-b25b-4f1c-a1f3-552353e9023d] - type ':remote console' to return to local mode
gremlin> baos = new ByteArrayOutputStream();[]
gremlin> graph.io(IoCore.graphml()).writer().normalize(true).create().writeGraph(baos, graph);[]
gremlin> new String(baos.toByteArray(), java.nio.charset.StandardCharsets.UTF_8)
==><?xml version="1.0" ?>
<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.1/graphml.xsd">
<key id="age" for="node" attr.name="age" attr.type="int"></key>
<key id="labelV" for="node" attr.name="labelV" attr.type="string"></key>
<key id="lang" for="node" attr.name="lang" attr.type="string"></key>
<key id="name" for="node" attr.name="name" attr.type="string"></key>
<key id="labelE" for="edge" attr.name="labelE" attr.type="string"></key>
<key id="weight" for="edge" attr.name="weight" attr.type="double"></key>
<graph id="G" edgedefault="directed">
<node id="1">
<data key="labelV">person</data>
<data key="age">29</data>
<data key="name">marko</data>
</node>
...
</graphml>
gremlin> :remote console
==>All scripts will now be evaluated locally - type ':remote console' to return to remote mode for Gremlin Server - [localhost/127.0.0.1:8182]-[df3107c1-b25b-4f1c-a1f3-552353e9023d]
gremlin> result
==>result{object=<?xml version="1.0" ?>
<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.1/graphml.xsd">
<key id="age" for="node" attr.name="age" attr.type="int"></key>
<key id="labelV" for="node" attr.name="labelV" attr.type="string"></key>
<key id="lang" for="node" attr.name="lang" attr.type="string"></key>
<key id="name" for="node" attr.name="name" attr.type="string"></key>
<key id="labelE" for="edge" attr.name="labelE" attr.type="string"></key>
<key id="weight" for="edge" attr.name="weight" attr.type="double"></key>
<graph id="G" edgedefault="directed">
<node id="1">
<data key="labelV">person</data>
<data key="age">29</data>
<data key="name">marko</data>
</node>
...
</graphml> class=java.lang.String}
gremlin> result.get(0).getString()
==><?xml version="1.0" ?>
<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.1/graphml.xsd">
<key id="age" for="node" attr.name="age" attr.type="int"></key>
<key id="labelV" for="node" attr.name="labelV" attr.type="string"></key>
<key id="lang" for="node" attr.name="lang" attr.type="string"></key>
<key id="name" for="node" attr.name="name" attr.type="string"></key>
<key id="labelE" for="edge" attr.name="labelE" attr.type="string"></key>
<key id="weight" for="edge" attr.name="weight" attr.type="double"></key>
<graph id="G" edgedefault="directed">
<node id="1">
<data key="labelV">person</data>
<data key="age">29</data>
<data key="name">marko</data>
</node>
...
</graph>
</graphml>
gremlin>
My Gremlin Console example sends scripts to the server for execution in a session (thus this approach will also work as a script sent from drivers assuming it is sent as one script or if using session each line can be sent individually). Note that the result of each line returned from the server is stored in a result variable in the console. For this to work properly it is important that you connect with a configuration like the one presented in the default remote-objects.yaml where objects are returned rather than just string representations, though in this case since the ultimate object is a String it might not matter so much. I suppose whether or not it depends on what you intend to do with the result itself once you have it.
Some caveats to consider:
For a large graph this operation will be fairly expensive because not only is it a full graph scan but you're also writing the entire graph to memory before streaming it back.
The use of the Graph API (i.e. graph.io()) and/or direct use of GraphWriter implementations isn't recommended, so I suppose these APIs could disappear in future versions but give that there aren't better solutions at this time there isn't much choice I'm afraid.
Related
I have this graphML file, which was created with yworks yEd.
Now I want to read this file into R to plot it via visNetwork. But reading the file into R using the igraph::read_graph function fails:
library(igraph)
example <- igraph::read_graph("data/graphml_example.graphml", format = "graphml")
Warning messages:
1: In read.graph.graphml(file, ...) : At foreign-graphml.c:651
:Ignoring because of a missing or unknown 'attr.type'
attribute
...
This is the graphml file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!--Created by yFiles for HTML 2.0.1.4-->
<graphml xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml.html/2.0/ygraphml.xsd " xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:demostyle="http://www.yworks.com/yFilesHTML/demos/FlatDemoStyle/1.0" xmlns:bpmn="http://www.yworks.com/xml/yfiles-for-html/bpmn/2.0" xmlns:demotablestyle="http://www.yworks.com/yFilesHTML/demos/FlatDemoTableStyle/1.0" xmlns:compat="http://www.yworks.com/xml/yfiles-compat-arrows/1.0" xmlns:VuejsNodeStyle="http://www.yworks.com/demos/yfiles-vuejs-node-style/1.0" xmlns:y="http://www.yworks.com/xml/yfiles-common/3.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/3.0" xmlns:yjs="http://www.yworks.com/xml/yfiles-for-html/2.0/xaml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<key id="d0" for="node" attr.type="boolean" attr.name="Expanded" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/folding/Expanded">
<default>true</default>
</key>
<key id="d1" for="node" attr.name="NodeLabels" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/NodeLabels"/>
<key id="d2" for="node" attr.name="NodeGeometry" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/NodeGeometry"/>
<key id="d3" for="all" attr.name="UserTags" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/UserTags"/>
<key id="d4" for="node" attr.name="NodeStyle" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/NodeStyle"/>
<key id="d5" for="node" attr.name="NodeViewState" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/folding/1.1/NodeViewState"/>
<key id="d6" for="edge" attr.name="EdgeLabels" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/EdgeLabels"/>
<key id="d7" for="edge" attr.name="EdgeGeometry" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/EdgeGeometry"/>
<key id="d8" for="edge" attr.name="EdgeStyle" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/EdgeStyle"/>
<key id="d9" for="edge" attr.name="EdgeViewState" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/folding/1.1/EdgeViewState"/>
<key id="d10" for="port" attr.name="PortLocationParameter" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/PortLocationParameter">
<default>
<x:Static Member="y:FreeNodePortLocationModel.NodeCenterAnchored"/>
</default>
</key>
<key id="d11" for="port" attr.name="PortStyle" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/PortStyle">
<default>
<x:Static Member="y:VoidPortStyle.Instance"/>
</default>
</key>
<key id="d12" for="port" attr.name="PortViewState" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/folding/1.1/PortViewState"/>
<key id="d13" attr.name="SharedData" y:attr.uri="http://www.yworks.com/xml/yfiles-common/2.0/SharedData"/>
<data key="d13">
<y:SharedData>
<yjs:Color x:Key="1" value="#FF316C94"/>
<yjs:Color x:Key="2" value="#FF006A70"/>
<yjs:Color x:Key="3" value="#FFC9E2E2"/>
<yjs:Arrow x:Key="4" type="NONE"/>
</y:SharedData>
</data>
<graph id="G" edgedefault="directed">
<node id="n0">
<data key="d1">
<x:List>
<y:Label>
<y:Label.Text>A</y:Label.Text>
<y:Label.LayoutParameter>
<y:RatioAnchoredLabelModelParameter LayoutOffset="45.2981354349738,20.5"/>
</y:Label.LayoutParameter>
<y:Label.Style>
<yjs:DefaultLabelStyle horizontalTextAlignment="CENTER" autoFlip="false" textFill="#FFFFFFFF" textSize="16">
<yjs:DefaultLabelStyle.font>
<yjs:Font fontSize="16" fontFamily="Calibri" fontWeight="BOLD"/>
</yjs:DefaultLabelStyle.font>
</yjs:DefaultLabelStyle>
</y:Label.Style>
</y:Label>
</x:List>
</data>
<data key="d2">
<y:RectD X="1917.9576310558555" Y="2912.1062122893554" Width="214.8931458699476" Height="57"/>
</data>
<data key="d4">
<demostyle:FlowchartNodeStyle type="terminator">
<demostyle:FlowchartNodeStyle.stroke>
<yjs:Stroke fill="#FF000000" miterLimit="1.45" thickness="2"/>
</demostyle:FlowchartNodeStyle.stroke>
<demostyle:FlowchartNodeStyle.fill>
<yjs:LinearGradient spreadMethod="PAD" startPoint="0,0" endPoint="1,1">
<yjs:GradientStop color="{y:GraphMLReference 1}" offset="0"/>
<yjs:GradientStop color="{y:GraphMLReference 1}" offset="1"/>
</yjs:LinearGradient>
</demostyle:FlowchartNodeStyle.fill>
</demostyle:FlowchartNodeStyle>
</data>
<port name="p0"/>
</node>
<node id="n1">
<data key="d1">
<x:List>
<y:Label>
<y:Label.Text>B</y:Label.Text>
<y:Label.LayoutParameter>
<y:RatioAnchoredLabelModelParameter LayoutOffset="68.91532293497403,12.5"/>
</y:Label.LayoutParameter>
<y:Label.Style>
<yjs:DefaultLabelStyle horizontalTextAlignment="CENTER" autoFlip="false" textFill="#FFFFFFFF" textSize="16">
<yjs:DefaultLabelStyle.font>
<yjs:Font fontSize="16" fontFamily="Calibri" fontWeight="BOLD"/>
</yjs:DefaultLabelStyle.font>
</yjs:DefaultLabelStyle>
</y:Label.Style>
</y:Label>
</x:List>
</data>
<data key="d2">
<y:RectD X="1917.9576310558555" Y="2809.9061759957385" Width="214.89314586994806" Height="57"/>
</data>
<data key="d4">
<demostyle:FlowchartNodeStyle type="document">
<demostyle:FlowchartNodeStyle.stroke>
<yjs:Stroke fill="#FF000000" miterLimit="1.45" thickness="2"/>
</demostyle:FlowchartNodeStyle.stroke>
<demostyle:FlowchartNodeStyle.fill>
<yjs:LinearGradient spreadMethod="PAD" startPoint="0,0" endPoint="1,1">
<yjs:GradientStop color="{y:GraphMLReference 2}" offset="0"/>
<yjs:GradientStop color="{y:GraphMLReference 2}" offset="1"/>
</yjs:LinearGradient>
</demostyle:FlowchartNodeStyle.fill>
</demostyle:FlowchartNodeStyle>
</data>
<port name="p0"/>
<port name="p1"/>
<port name="p2"/>
</node>
<node id="n2">
<data key="d1">
<x:List>
<y:Label>
<y:Label.Text>X</y:Label.Text>
<y:Label.LayoutParameter>
<y:RatioAnchoredLabelModelParameter LayoutOffset="62.41922918497403,20.5"/>
</y:Label.LayoutParameter>
<y:Label.Style>
<yjs:DefaultLabelStyle horizontalTextAlignment="CENTER" autoFlip="false" textFill="#FF000000" textSize="16">
<yjs:DefaultLabelStyle.font>
<yjs:Font fontSize="16" fontFamily="Calibri" fontWeight="BOLD"/>
</yjs:DefaultLabelStyle.font>
</yjs:DefaultLabelStyle>
</y:Label.Style>
</y:Label>
</x:List>
</data>
<data key="d2">
<y:RectD X="1917.9576310558555" Y="2702.7061397021216" Width="214.89314586994806" Height="57"/>
</data>
<data key="d4">
<demostyle:FlowchartNodeStyle type="start1">
<demostyle:FlowchartNodeStyle.stroke>
<yjs:Stroke fill="#FF000000" miterLimit="1.45" thickness="2"/>
</demostyle:FlowchartNodeStyle.stroke>
<demostyle:FlowchartNodeStyle.fill>
<yjs:LinearGradient spreadMethod="PAD" startPoint="0,0" endPoint="1,1">
<yjs:GradientStop color="{y:GraphMLReference 3}" offset="0"/>
<yjs:GradientStop color="{y:GraphMLReference 3}" offset="1"/>
</yjs:LinearGradient>
</demostyle:FlowchartNodeStyle.fill>
</demostyle:FlowchartNodeStyle>
</data>
<port name="p0"/>
</node>
<edge id="e0" source="n1" target="n0" sourceport="p0" targetport="p0">
<data key="d7">
<x:List>
<y:Bend Location="2025.4042039908295,2898.850638702741"/>
</x:List>
</data>
<data key="d8">
<yjs:PolylineEdgeStyle sourceArrow="{y:GraphMLReference 4}">
<yjs:PolylineEdgeStyle.stroke>
<yjs:Stroke fill="#FF000000" miterLimit="1.45"/>
</yjs:PolylineEdgeStyle.stroke>
<yjs:PolylineEdgeStyle.targetArrow>
<yjs:Arrow stroke="#FF000000" fill="#FF000000"/>
</yjs:PolylineEdgeStyle.targetArrow>
</yjs:PolylineEdgeStyle>
</data>
</edge>
<edge id="e1" source="n2" target="n1" sourceport="p0" targetport="p2">
<data key="d8">
<yjs:PolylineEdgeStyle sourceArrow="{y:GraphMLReference 4}">
<yjs:PolylineEdgeStyle.stroke>
<yjs:Stroke fill="#FF000000" miterLimit="1.45"/>
</yjs:PolylineEdgeStyle.stroke>
<yjs:PolylineEdgeStyle.targetArrow>
<yjs:Arrow stroke="#FF000000" fill="#FF000000"/>
</yjs:PolylineEdgeStyle.targetArrow>
</yjs:PolylineEdgeStyle>
</data>
</edge>
</graph>
</graphml>
How can I read this into R so that properties like shape and color are preserved?
I am using a many to one mapping in BizTalk, to generate an output schema with data generated using a cross product logic on a node of input schemas.
Following figure depicts what I've done yet:
The sample input xmls are as follows:
<!-Schema1 Instance-->
<Root>
<Data>
<ItemCode>10</ItemCode>
<ItemCost>1024</ItemCost>
</Data>
<Data>
<ItemCode>20</ItemCode>
<ItemCost>2048</ItemCost>
</Data>
</Root>
<!-Schema2 Instance-->
<Root>
<Data>
<Code>10</Code>
<ShipAddr>addr11101</ShipAddr>
</Data>
<Data>
<Code>30</Code>
<ShipAddr>addr33301</ShipAddr>
</Data>
<Data>
<Code>20</Code>
<ShipAddr>addr22201</ShipAddr>
</Data>
<Data>
<Code>10</Code>
<ShipAddr>addr11102</ShipAddr>
</Data>
</Root>
The required output is based on a cross product performed based on equality of Schema1.ItemCode and Schema2.Code. Sample is as follows:
<!--Output Schema Instance required; Order of records is irrelevant-->
<Root>
<Data>
<Code>10</Code>
<ItemCost>1024</ItemCost>
<ShipAddr>addr11101</ShipAddr>
</Data>
<Data>
<Code>20</Code>
<ItemCost>2048</ItemCost>
<ShipAddr>addr22201</ShipAddr>
</Data>
<Data>
<Code>10</Code>
<ItemCost>1024</ItemCost>
<ShipAddr>addr11102</ShipAddr>
</Data>
</Root>
Actual output:
Output with no looping functoid
XML Output
<ns0:Root xmlns:ns0="http://TestTO_DELETE.SchemaOut">
<Data>
<Code>10</Code><ItemCost>1024</ItemCost><ShipAddr>addr11101</ShipAddr>
</Data>
<Data><Code>20</Code></Data>
</ns0:Root>
Output with both looping functoids connections 1, and 2
XML Output
<ns0:Root xmlns:ns0="http://TestTO_DELETE.SchemaOut">
<Data>
<Code>10</Code>
</Data>
<Data>
<Code>20</Code>
</Data>
<Data />
<Data />
<Data />
<Data />
</ns0:Root>
Output with single looping functoid connection 1
XML Output
<ns0:Root xmlns:ns0="http://TestTO_DELETE.SchemaOut">
<Data>
<Code>10</Code><ItemCost>1024</ItemCost><ShipAddr>addr11101</ShipAddr>
</Data>
<Data>
<Code>20</Code>
</Data>
</ns0:Root>
Please suggest how to proceed in such scenario?
I tried various combinations of functoids to get the required output schema, but nothing worked. So, I finally moved on to use scripting functoid, which served my purpose. I am posting my finding as it could be helpful to someone else.
This is how I proceeded:
Remove all connections and functoids from the map
Add a scripting functoid
Connect InputMesagePart_0 to input of scripting functoid
Connect Scripting functoid to the first element node of the output schema
In the Script Functoid Configuration, add the transformation logic. For e.g., in my case the logic was:
<xsl:template name="Template1">
<xsl:param name="MessagePart_0_Xml" /> <!--Not used anywhere-->
<xsl:variable name="Msg_0_RootNode" select="/*[local-name()='Root']/*[local-name()='InputMessagePart_0']/*[local-name()='Root']" />
<xsl:variable name="Msg_1_RootNode" select="/*[local-name()='Root']/*[local-name()='InputMessagePart_1']/*[local-name()='Root']" />
<xsl:for-each select="$Msg_0_RootNode/Data">
<xsl:variable name="Msg_0_DataNode" select="." />
<xsl:for-each select="$Msg_1_RootNode/Data">
<xsl:variable name="Msg_1_DataNode" select="." />
<xsl:if test="$Msg_0_DataNode/ItemCode/text() = $CostCenterDataNode/Code/text()">
<ItemCost>
<xsl:value-of select="$Msg_0_DataNode/ItemCost/text()" />
</ItemCost>
<ShipAddr>
<xsl:value-of select="$CostCenterDataNode/ShipAddr/text()" />
</ShipAddr>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
If there is a better way to approach this problem, please suggest.
I'm trying to write a graph to a file but I'm getting a different node labels than I would like.
Example Code:
g <- graph.star(2)
V(g)$name <- c('homer','marge')
write.graph(g,file = 'g.graphml',format = 'graphml')
Output:
<?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">
<!-- Created by igraph -->
<key id="g_name" for="graph" attr.name="name" attr.type="string"/>
<key id="g_mode" for="graph" attr.name="mode" attr.type="string"/>
<key id="g_center" for="graph" attr.name="center" attr.type="double"/>
<key id="v_name" for="node" attr.name="name" attr.type="string"/>
<graph id="G" edgedefault="directed">
<data key="g_name">In-star</data>
<data key="g_mode">in</data>
<data key="g_center">1</data>
<node id="n0"> ###### This should <node id = "homer">
<data key="v_name">homer</data>
</node>
<node id="n1"> ###### This should <node id = "marge">
<data key="v_name">marge</data>
</node>
<edge source="n1" target="n0">
</edge>
</graph>
</graphml>
I would like the "node id" attribute to be the names of the nodes (as shown in comments). Anybody have any ideas? Thanks!
You can't do this currently AFAIK. I am not sure why it is not implemented that way. Can you please open an issue about it at https://github.com/igraph/igraph/issues?state=open ? Thanks.
What transformer should I use to extract parameters from an http message like http://localhost:8088/?id=xxx&type=yyyy ans put the values of the id and the type parameters into a fixed soap request like :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsd="http://wsdouane/">
<soapenv:Header/>
<soapenv:Body>
<wsd:find>
<entity>
<id>xxxx</id>
<type>yyyy</type>
</entity>
</wsd:find>
</soapenv:Body>
</soapenv:Envelope>
Http output
Cannot bind to address "http://127.0.0.1:8088/" No component registered on that endpoint
File output
<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:findResponse xmlns:ns2="http://wsdouane/"/>
</S:Body>
</S:Envelope>
in order to pass to a JAX-WS web service?
thank you
The process of retrieving query params and setting them in an object and then into a SOAP object, is not a single step process with a single transformer.
Step 1: You can use
<http-request-to-parameter-map>
transformer to get the query params as a Map.
Step 2: Then use this map to create a object with the map vlaues.
Step 3: And then send the object to your JAX-WS client component.
More reference of the transformers and the http and servlet module references can be found at below links.
HTTP Transport Reference.
Servlet Transport Reference
Updated answer to use XSLT and proxy client.
<flow name="SOAPWebService" >
<http:inbound-endpoint address="http://localhost:8088/" exchange-pattern="request-response">
</http:inbound-endpoint>
<set-variable value="#[message.inboundProperties['id']]" variableName="paramId"></set-variable>
<set-variable value="#[message.inboundProperties['type']]" variableName="paramType"></set-variable>
<component class="com.example.components.SampleComponent" ></component>
<mule-xml:xslt-transformer
maxIdleTransformers="2" maxActiveTransformers="5"
xsl-file="C:\WorkSpace\MyProject\src\main\resources\xslt\PrepareRequestXML.xsl">
<mule-xml:context-property key="paramId"
value="#[flowVars['paramId']]" />
<mule-xml:context-property key="paramType"
value="#[flowVars['paramType']]" />
</mule-xml:xslt-transformer>
<cxf:proxy-client payload="body"
enableMuleSoapHeaders="true">
</cxf:proxy-client>
<http:outbound-endpoint exchange-pattern="request-response"
address="http://localhost:8080/ClientsDB/douane" doc:name="HTTP">
</http:outbound-endpoint>
<byte-array-to-string-transformer doc:name="Byte Array to String" />
<file:outbound-endpoint ....... .. />
</flow>
Below is the correct XSLT
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns="http://wsdouane/">
<xsl:output method="xml" indent="yes" />
<xsl:param name="paramType"></xsl:param>
<xsl:param name="paramId"></xsl:param>
<xsl:template match="*" >
<xsl:element name="find" namespace="http://wsdouane/">
<xsl:element name="entity">
<xsl:element name="id">
<xsl:value-of select="$paramType"/>
</xsl:element>
<xsl:element name="type">
<xsl:value-of select="$paramId"/>
</xsl:element>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="text()|processing-instruction()|comment()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The code for SampleComponent class is
package com.example.components;
import org.mule.api.MuleEventContext;
import org.mule.api.lifecycle.Callable;
public class SampleComponent implements Callable {
#Override
public Object onCall(MuleEventContext eventContext) throws Exception {
String str = "<sample> </sample>";
return str;
}
}
I have a listview which gets an xmldatasource as its datasource. The xmldatasource is created and assigned dynamically. Using xpath just before binding the data to the listview using
listview.datasource = myxmlsource
listview.DataBind()
only the node element is selected using xpath="root/node" .Hence I think the xml structure after the xpath is applied looks like the following:
<node name="Albert" age="32" desc="some random description" region="north"/>
<node name="Randy" age="32" desc="some random description" region="south"/>
<node name="Zebra" age="32" desc="some random description"region="east"/>
<node name="Bob" age="32" desc="some random description"region="south"/>
<node name="Carl" age="32" desc="some random description"region="north"/>
<node name="Denver" age="32" desc="some random description"region="east"/>
Note that it has no root. I'm trying to sort this XSLT.
The aim here is to group the xml by region and then sort the xml by
name.
I'm new to XSLT and it seems to be quite a beast.
so far the xslt code I could come up with is:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl my" xmlns:my="http://tempuri.org"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template name="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node() >
<xsl:sort select="#region" order="ascending"/>
<xsl:sort select="#name"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
The expected output after grouping by region and sorting by name is:
<node name="Denver" age="32" desc="some random description"region="east"/>
<node name="Zebra" age="32" desc="some random description"region="east"/>
<node name="Albert" age="32" desc="some random description" region="north"/>
<node name="Carl" age="32" desc="some random description"region="north"/>
<node name="Bob" age="32" desc="some random description"region="south"/>
<node name="Randy" age="32" desc="some random description" region="south"/>
Update:
I forgot to mention:
The ordering of the grouping by region need not necessarily be ascending or descending but can be based on any custom condition such as north first, east second and south third. How to achieve a custom ordering?
I tried the following and some more stuff similar and I get
This document already has a 'DocumentElement' node.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="node[#region='north']" >
<xsl:sort select="#name"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:copy>
<xsl:apply-templates select="node[#region='east']" >
<xsl:sort select="#name"/>
</xsl:apply-templates>
</xsl:copy>
<xsl:copy>
<xsl:apply-templates select="node[#region='south']" >
<xsl:sort select="#name"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Your XSLT is almost right - the template should have a match="..." instead than a name="..." attribute - here is the working version:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl my" xmlns:my="http://tempuri.org"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()">
<xsl:sort select="#region" order="ascending"/>
<xsl:sort select="#name"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>