|
Hi,
well I'm trying to use the distinct-nodes function and I've added all sorts of namespaces now. it looks like this:-
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2004/07/xpath-functions"
xmlns:functx="http://www.functx.com"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:my-scripts"
>
-------------------------------------------------
and I'm trying to use it like this:
<xsl:for-each select="functx:distinct-nodes('Inputs/*')">
<td><xsl:value-of select="name()"></xsl:value-of></td>
</xsl:for-each>
----------------------------------------------------
the error is this
The XML page cannot be displayed
Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.
--------------------------------------------------------------------------------
Namespace 'http://www.functx.com' does not contain any functions.
Can u plz help me with this, I can't seem to figure out where I'm going wrong
Thanks in advance
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
Hello everyone,
I'm back again with another problem!!
well I'm trying to display data from an Xml file in the form of a table. for that I'm using XSL and the problem is that now I wanna make the xsl able to display different number of columns in the table.
the data can be in any form such as
<Outputs>
<Compound>BiPhenyl</Compound>
<Value>0.000000005</Value>
<Compound>BiPhenyl</Compound>
<Value>0.000000005</Value>
<Compound>BiPhenyl</Compound>
<Value>0.000000005</Value>
<Compound>BiPhenyl</Compound>
<Value>0.000000005</Value>
<Compound>BiPhenyl</Compound>
<Value>0.000000005</Value>
<Compound>H2O</Compound>
<Value>0.703552320</Value>
</Outputs>
or...
<Outputs>
<Value>0.000018075</Value>
</Outputs>
and the headiings of the columns shoulbe the heading nodes. as you can see in teh previous example that the node name 'compound' and 'value' are reapeated every time for each value but i just need them once.
So the point is that there can be different number of columns to display. How can I make such an arrangement that the xsl should pick up the unique names of the columns and then I can easily go thru the data using foreach and display it.
Thanks in advance
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
I'm using VB.Net 03 and trying to parse a very large document (cannot make smaller). How do I go about using XMLReader (I'm assuming that's what I would use) to parse XML file against XSL file?
Right now I'm having to programmatically split out the file and parse.
murf
|
|
|
|
|
Hi,
am working on VS.net 2.0 windows application using c#.
while am reading value of node in xml doc it is giving empty string.pls see the code below. can any one give me the solution where I had done mistake.
XmlTextReader reader = new XmlTextReader(@"C:\book.xml");
while (reader.Read())
{
reader.MoveToElement();
if (reader.Name == "year")
{
label1.Text = reader.Value.ToString();
}
}
book.xml file:
<code<?xml version="1.0" encoding="utf-8" ?="">
<bookstore>
<book category="COOKING">
<title lang="en"> Everyday Italian < /title>
<author>Giada De Laurentiis </author>
<year>2005 </year>
<price>30.00 </price>
</book>
</bookstore>
Thanks
-- modified at 7:22 Thursday 6th September, 2007
|
|
|
|
|
You can directly read the xml file in DataSet
using
ds.ReadXML("xmlfilename.xml");
now you can get each Tag as Columns
Best Regards,
Chetan Patel
|
|
|
|
|
XmlTextReader reader = null;
try
{
//Load the reader with the XML file.
reader = new XmlTextReader("c:\\book.xml");
//Parse the XML and display the text content of each of the elements.
while (reader.Read()){
if (reader.IsStartElement()){
if (reader.IsEmptyElement)
Console.WriteLine("<{0}/>", reader.Name);
else{
Console.Write("<{0}> ", reader.Name);
reader.Read(); //Read the start tag.
if (reader.IsStartElement()) //Handle nested elements.
Console.Write("\r\n<{0}>", reader.Name);
Console.WriteLine(reader.ReadString()); //Read the text content of the element.
}
}
}
}
finally
{
if (reader != null)
reader.Close();
}
try this code and remove space in your xml title closing tag in between < and / and put label1.text or what you like instead of Console.WriteLine .
<bookstore>
<book category="COOKING">
<title lang="en"> Everyday Italian !!< /title>!!
<author>Giada De Laurentiis </author>
<year>2005 </year>
<price>30.00 </price>
</book>
</bookstore>
Israr Ali
|
|
|
|
|
Hello everyone,
well I want to make this one as simple as I can.
I have an XML inwhich you can get nodes in this type of format
<LOG>
<LogConfiguration>
</LogConfiguration>
<CallSequence>
<Call>
<ObjectType></ObjectType>
<ObjectName></ObjectName>
<Interface></Interface>
<Method></Method>
<ReturnCode></ReturnCode>
</Call>
<Call>
<ObjectType></ObjectType>
<ObjectName></ObjectName>
<Interface></Interface>
<Method></Method>
<Arguments></Arguments>
<CallSequence>
<Call>....</Call>
</CallSequence>
</LOG>
Now what I'm trying to do is to traverse it recursively using just a single template to tranverse both the /LOG/CallSequence/Call and any CallSequence/Call Elements that occur inside it. So can anyone plz give me an idea of how to do this.
I have made a template that traverses the outer part but i dont know how to reach the inside CallSequence/Call part???!!!
Thanks in advance!
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
Here is an example:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<title>Call Sequence</title>
</head>
<body>
<xsl:apply-templates select="."/>
</body>
</html>
</xsl:template>
<xsl:template match="CallSequence">
<xsl:for-each select="Call">
<xsl:choose>
<xsl:when test="CallSequence">
<xsl:apply-templates select="CallSequence"/>
</xsl:when>
<xsl:otherwise>
<!--Process the other child nodes-->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
That looks preetu helpful but the problem is that the xsl I'm working on is very large and accessing the CallSequence/Call is used at two places. So I wanted to use the same template for both. that is for outer as well the inner occurence. The XML can contain any number of call sequences within a call as u know a method can call another method and that can call yet another one so what i'm trying to do is to develop a template which i can call by passing it the set of nodes. Then it should display it.
by the way if we use xsl:template match="CallSequence"... is it able to get all the CallSequence nodes as we traverse down the tree??
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
its giving an error
The XSL processor stack has overflowed - probable cause is infinite template recursion
what should be the termination condition in this?
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
<xsl:apply-templates select="CallSequence"/> is the recursive call and will be called if "CallSequence" is a child of itself at any point. If you call this more than once within your xsl:for-each loop, you will run out of stack. Also, it should return once it does not find another child "CallSequence"; however, if your xsl:for-each does not account for a recursive call, it will cause an out-of stack error also. It is very hard to troubleshoot a large template with nested xsl:for-each loops. I advise you to break up your code into several templates. XSLT is functional in nature and you should keep nested levels of xsl:for-each to a minimum.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
OK that looks helpful to me! Please tell what this statement is doing
<xsl:apply-templates select="."/>
in the example code you've given, When I changed the . to CallSequence it doesnt show anything (atleast the error is gone) but when i put this as you have given it runs out of stack. right now I'm just trying to run your code in order to make an understanding of the template I wanna make at the moment. After I'm done with this I'll concentrate on embedding it in the whole this as a sepearte function like you said
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
Sorry, my mistake. The "." means current node. It should be "CallSequence".
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
well now I've changed the <xsl:apply-templates select="."/> to
<xsl:apply-templates select="*"/>
and its showing the output BUT... as I was thinking... the Call Node that has other CallSequence nodes is comming out at the end bcz of the stack. Actually the calling function should come at the top rather than at the bottom.
Right now I'm thinking abt another way around. How abt if I use a template to display the Nodes inside a Call and if there is yet another CallSequence I call that template again (using Call-template) with the new Node Set.
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
<xsl:template name="CallSequenceTemplate">
<xsl:param name="nodeset"/>
<xsl:for-each select="msxsl:node-set($nodeset)/CallSequence/Call">
<table>
<br/>
<tr>
<td class='heading3'><b>Call to <xsl:value-of select="Method"/></b></td>
</tr>
</table>
<table width="100%">
<tr><td width="10%">Object Type </td><td><i><xsl:value-of select="ObjectType"/></i></td></tr>
<tr><td>Object Name </td><td><i><xsl:value-of select="ObjectName"/></i></td></tr>
<tr><td>Interface Name </td><td><i><xsl:value-of select="Interface"/></i></td></tr>
<tr><td>Return Code </td><td><i><xsl:value-of select="ReturnCode"/></i></td></tr>
</table>
<xsl:for-each select="Arguments">
<table width = "100%" border="0" class="border" cellpadding="0" cellspacing="1">
<tr><td class='heading4'> </td></tr>
<xsl:if test="Results/Value">
<tr class="nonSelectedRow">
<td colspan="6" class = 'detail_table_element'><b>Inputs</b></td>
</tr>
</xsl:if>
<xsl:if test="Results/Compound">
<tr class="nonSelectedRow">
<td colspan="4" class = 'detail_table_element'><b>Inputs</b></td>
<td colspan="2" class = 'detail_table_element'><b>Output</b></td>
</tr>
</xsl:if>
<tr class="nonSelectedRow">
<xsl:for-each select="*[name() != 'Results'] | Results/child::node()[1] | Results/child::node()[1] / child::node()[2]">
<th><xsl:value-of select="name()"/></th>
</xsl:for-each>
</tr>
<tr>
<xsl:for-each select="*[node() and name() != 'Results']">
<td valign = "top"><xsl:value-of select="node()"/></td>
</xsl:for-each>
<xsl:if test="Results/Compound">
<td>
<table border="0" width = "100%">
<xsl:for-each select="Results/Compound">
<tr>
<td><xsl:value-of select="Name"/></td>
</tr>
</xsl:for-each>
</table>
</td>
<td>
<table border="0" width = "100%">
<xsl:for-each select="Results/Compound">
<tr>
<td><xsl:value-of select="Value"/></td>
</tr>
</xsl:for-each>
</table>
</td>
</xsl:if>
<xsl:if test="Results/Value">
<xsl:for-each select="Results">
<td><xsl:value-of select="Value"/></td>
</xsl:for-each>
</xsl:if>
</tr>
</table>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
-----------------
I've almost done it!! the calling doesnt go to the third level so I call it this way...
<xsl:call-template name="CallSequenceTemplate">
<xsl:with-param name="nodeset" select="/LOG"/>
</xsl:call-template>
<xsl:call-template name="CallSequenceTemplate">
<xsl:with-param name="nodeset" select="/LOG/CallSequence/Call"/>
</xsl:call-template>
The only problem now is that as its taking All the call which are at the same level. It ignores the sequence of call for example when a method is called after lots of nested calls in a previous method.
Thanks very much u know I really appreciate your effort. I wouldnt have done this with out u.
Thanks!
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
You just have to remember that xsl:call-template works with the current node and doesn't change scope like xsl:apply-templates. Also, xsl:apply-templates has a mode attribute that is used to name it like xsl:call-templates and you can pass parameters to it also.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
wht does it mean when we say that call-template doesnt change scope? bcz after this statement the xsl:template gets called right? so we can change the scope inside the template right?
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
xsl:call-template has is own "scope" as far as variable creation. But the scope of the current node and node-list is the same as its calling parent.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
OK! can u tel me how can we get the parent node of the current node.
<xsl:if test="name()='CallSequence'"><!--Need some fixing to get the sequence right-->
<xsl:apply-templates select="parent()"/>
</xsl:if>
I was thinking that while traversing through the $nodeset I shoujld chk for the existance of another CallSequence Node and the call the same template again recursively.
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
It can be "parent::node()" or "parent::*". I think you can specifically check if the parent has a specific name by using "parent::CallSequence"!
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
I was thinking abt starting a new articles on this but then I changed my mind again... I'm back to the recursive solution again bcz the previous one wasn't showing the right sequence and this recursive one gets a nodeset missed when it starts recursion.
I'm giving the template I made and the XML I'm using.
Here comes the Template!
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<link rel="stylesheet" type="text/css" href="log_style.css" />
<title>Recursive Solution</title>
</head>
<body>
<xsl:apply-templates select="*"/>
</body>
</html>
</xsl:template>
<!--<xsl:template match="CallSequence">
<xsl:for-each select="Call">
<xsl:choose>
<xsl:when test="CallSequence">
<xsl:apply-templates select="CallSequence"/>
</xsl:when>
<xsl:otherwise>
Process the other child nodes
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
-->
<!--Starting: TRYING THE NEW TEMPLATE.... USING Call-Template function-->
<xsl:template name="CallSequenceTemplate" match="CallSequence">
<xsl:for-each select="Call">
<xsl:choose>
<xsl:when test="CallSequence">
<xsl:apply-templates select="CallSequence"/>
</xsl:when>
<xsl:otherwise>
<table>
<br/>
<tr>
<td class='heading3'><b>Call to <xsl:value-of select="Method"/></b></td>
</tr>
</table>
<table width="100%">
<tr><td width="10%">Object Type </td><td><i><xsl:value-of select="ObjectType"/></i></td></tr>
<tr><td>Object Name </td><td><i><xsl:value-of select="ObjectName"/></i></td></tr>
<tr><td>Interface Name </td><td><i><xsl:value-of select="Interface"/></i></td></tr>
<tr><td>Return Code </td><td><i><xsl:value-of select="ReturnCode"/></i></td></tr>
</table>
<xsl:for-each select="Arguments">
<table width = "100%" border="0" class="border" cellpadding="0" cellspacing="1">
<tr><td class='heading4'> </td></tr>
<xsl:if test="Results/Value">
<tr class="nonSelectedRow">
<td colspan="6" class = 'detail_table_element'><b>Inputs</b></td>
</tr>
</xsl:if>
<xsl:if test="Results/Compound">
<tr class="nonSelectedRow">
<td colspan="4" class = 'detail_table_element'><b>Inputs</b></td>
<td colspan="2" class = 'detail_table_element'><b>Output</b></td>
</tr>
</xsl:if>
<tr class="nonSelectedRow">
<xsl:for-each select="*[name() != 'Results'] | Results/child::node()[1] | Results/child::node()[1] / child::node()[2]">
<th><xsl:value-of select="name()"/></th>
</xsl:for-each>
</tr>
<tr>
<xsl:for-each select="*[node() and name() != 'Results']">
<td valign = "top"><xsl:value-of select="node()"/></td>
</xsl:for-each>
<xsl:if test="Results/Compound">
<td>
<table border="0" width = "100%">
<xsl:for-each select="Results/Compound">
<tr>
<td><xsl:value-of select="Name"/></td>
</tr>
</xsl:for-each>
</table>
</td>
<td>
<table border="0" width = "100%">
<xsl:for-each select="Results/Compound">
<tr>
<td><xsl:value-of select="Value"/></td>
</tr>
</xsl:for-each>
</table>
</td>
</xsl:if>
<xsl:if test="Results/Value">
<xsl:for-each select="Results">
<td><xsl:value-of select="Value"/></td>
</xsl:for-each>
</xsl:if>
</tr>
</table>
</xsl:for-each> <!--Arguments foreach ending-->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each> <!--Main outer foreach ending-->
</xsl:template><!--CallSequenceTemplate Ending-->
<!--Ending: TRYING THE NEW TEMPLATE.... USING Call-Template function-->
</xsl:stylesheet>
------------------
AND here's the XML
-----------------
<?xml version="1.0" encoding="utf-8"?>
<?xml:stylesheet type="text/xsl" href="d:\\unit example recursive.xsl"?>
<LOG>
<LoggedProgram>C:\Program Files\AspenTech\Aspen HYSYS 2004\hysys.exe</LoggedProgram>
<LogConfiguration>C:\Program Files\Co-LaN\CAPE-OPEN Logger\CAPE-OPENLogs.ini</LogConfiguration>
<LoggedComponent>
<Name>MixNSplit 12</Name>
<CAPE-OPENVersion>1.0</CAPE-OPENVersion>
<Implementation>DLL</Implementation>
<Location>C:\Program Files\Common Files\AspenTech Shared\CAPE-OPEN Example Models\AspenCOUnit100.dll</Location>
<LoggerStatus>Loaded Successfully</LoggerStatus>
</LoggedComponent>
<CallSequence>
<Call>
<ObjectType>Unit</ObjectType>
<ObjectName>ChemSepUO_382</ObjectName>
<Interface>ICapeUnit</Interface>
<Method>get_ports</Method>
<ReturnCode>No Error</ReturnCode>
</Call>
<Call>
<ObjectType>Unit</ObjectType>
<ObjectName>ChemSepUO_382</ObjectName>
<Interface>ICapeUnit</Interface>
<Method>Validate</Method>
<ReturnCode>No Error</ReturnCode>
<Message>No inlet streams have been connected to this block</Message>
</Call>
<Call>
<ObjectType>Unit</ObjectType>
<ObjectName>ChemSepUO_382</ObjectName>
<Interface>ICapeUnit</Interface>
<Method>Calculate</Method>
<CallSequence>
<Call>
<ObjectType>Material Object</ObjectType>
<ObjectName>Mix out</ObjectName>
<Interface>ICapeThermoMaterialObject</Interface>
<Method>SetProp</Method>
<Arguments>
<Property>Volume</Property>
<Phase>Overall</Phase>
<Basis>Mole</Basis>
<Calc>Mixture</Calc>
<Results>
<Value>0.000018075</Value>
</Results>
</Arguments>
<ReturnCode>No Error</ReturnCode>
</Call>
<Call>
<ObjectType>Material Object</ObjectType>
<ObjectName>Mix out</ObjectName>
<Interface>ICapeThermoMaterialObject</Interface>
<Method>GetProp</Method>
<Arguments>
<Property>Fraction</Property>
<Phase>Overall</Phase>
<Basis>mole</Basis>
<Calc>null</Calc>
<Results>
<Compound>
<Name>Hydrogen</Name>
<Value>0.355979900</Value>
</Compound>
<Compound>
<Name>Methane</Name>
<Value>0.018735784</Value>
</Compound>
<Compound>
<Name>Benzene</Name>
<Value>0.401813320</Value>
</Compound>
<Compound>
<Name>Toluene</Name>
<Value>0.223470992</Value>
</Compound>
<Compound>
<Name>BiPhenyl</Name>
<Value>0.000000005</Value>
</Compound>
<Compound>
<Name>H2O</Name>
<Value>0.703552320</Value>
</Compound>
</Results>
</Arguments>
<ReturnCode>No Error</ReturnCode>
</Call>
</CallSequence>
<ReturnCode>No Error</ReturnCode>
</Call>
<Call>
<ObjectType>testing object</ObjectType>
<ObjectName>Backto 1st</ObjectName>
<Interface>Rocky</Interface>
<Method>Checking the sequence </Method>
<ReturnCode>no</ReturnCode>
<Message>checking the back track</Message>
</Call>
</CallSequence>
</LOG>
---------------------------------------------------
I'm sorry for giving such a long post but if u see the results u can see what the problem is... Can u or any buddy plz remove this bug!!. I've tried my heart out since yesterday and its not working!
Rocky
You can't climb up a ladder with your hands in your pockets.
-- modified at 2:44 Friday 7th September, 2007
|
|
|
|
|
I've found why this is missing the calling functions data
<xsl:template match="CallSequence">
<xsl:for-each select="Call">
<xsl:choose>
<xsl:when test="CallSequence">
<xsl:apply-templates select="CallSequence"/>
</xsl:when>
<xsl:otherwise>
<!--Process the other child nodes-->
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
As you can see this isthe basic model of recursion I'm using which was proposed by you previously. What happens is that that this condition in the choose-when actually doesnt consider whether there are some nodes above another CallSequence Clause.
<xsl:template match="CallSequence">
<xsl:for-each select="Call">
<xsl:choose>
<xsl:when test="CallSequence">
<xsl:apply-templates select="CallSequence"/>
</xsl:when>
--------------
see this section of XML
<Call>
<ObjectType>Unit</ObjectType>
<ObjectName>ChemSepUO_382</ObjectName>
<Interface>ICapeUnit</Interface>
<Method>Calculate</Method>
<CallSequence>
<Call>
--------------
I've tried to change the conditions but its no help
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
FINALLY !! I've DONE it... The EUREKA moment has come and I thought I should tell u first?
Thanks a lot George... Its been a pleasure!
"We make a living by what we get, we make a life by what we give." --Winston Churchill
That's definately true!
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|
|
Congrats! I bet you learned a lot about XSLT doing this exercise. Make sure you write down what you experienced for future reference.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
Yes. definately that was a really good one! I learned alot from that.
I'll definately make some notes and save that work as well.
Rocky
You can't climb up a ladder with your hands in your pockets.
|
|
|
|