|
Hi,
I'm loading an XML file generated by SQL Server 2005 and trying to locate certain nodes:
Dim d As New Xml.XmlDocument
d.Load(path)
If I use the following:
Dim lst As Xml.XmlNodeList = d.SelectNodes("//COLUMN")
then "lst" contains 0 nodes,
If I use this one instead:
Dim lst As Xml.XmlNodeList = d.GetElementsByTagName("COLUMN")
then "lst" is correctly filled.
Am I missing something important on XPath, XML...????
Or is it a VB.Net issue?
I don't think it's a .Net problem, because that very same code works on other xml files (with different tags).
|
|
|
|
|
Hi all,
I'm fairly new to xsl so please bare with me if this is a trivial issue.
I'm getting my XML from a database so it's just a string of row nodes with nodes representing the values of the row within.
Mostly it is one row per page. However, sometimes it is more, maximum 4 rows per page.
Each row node has a child node rowsequence which states what number row on the page the row should be.
So far I have been able to get to the beginning of each sequence of row nodes as follows:
<xsl:for-each select="ROWDATA/ROW">
<xsl:if test='BLOCKSEQUENCE=1'>
<xsl:call-template name="page"/>
</xsl:if>
</xsl:for-each>
However, I am not sure what to do next. How, to iterate over the following nodes that are supposed to be on the same page. all I can see is the logic should be: starting from the first node in the sequence keep iterating forward until you find a row node whose rowsequence node has a value of 1.
If anyone show me how to write this into XSL it would greatly appreciated.
Thank you for any help
PS
I'm using XSL 2.0 (Saxon 8)
Cheers
Tom
Philosophy: The art of never getting beyond the concept of life.
Religion: Morality taking credit for the work of luck.
|
|
|
|
|
Please post some sample XML data and the desired XSLT output so that I can help you better.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
Hi, thanks for the interest.
Here's a chunk of the XML, simplified so as not to consume too much space. As you can see there should be 3 pages of output. Whenever the BLOCKSEQUENCE value returns to 1 a new page started. Therefore, there should be three tables on three pages. The first table should have three rows. The second should have two rows and the third should have one row. I am at a loss as to how to iterate over this XML in such a way as how to do this.
<?xml version="1.0" ?>
<ROWDATA>
<ROW>
<TABLE_ROW_DETAILS>XSL-FO to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>1</BLOCKSEQUENCE>
</ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>2</BLOCKSEQUENCE>
</ROW>
<ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>3</BLOCKSEQUENCE>
</ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>1</BLOCKSEQUENCE>
</ROW>
<ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>2</BLOCKSEQUENCE>
</ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>1</BLOCKSEQUENCE>
</ROW>
</ROWDATA>
My XSL so far is as follows
<xsl:template match="/">
<fo:root>
<fo:layout-master-set>
<fo:simple-page-master margin-right="0.8cm" margin-left="0.8cm" margin-bottom="0.8cm" margin-top="0.8cm" page-width="29.7cm" page-height="21cm" master-name="A4-landscape">
<fo:region-body margin-bottom="1.5cm" margin-top="1.5cm"/>
<fo:region-before extent="1.5cm"/>
<fo:region-after extent="1.0cm"/>
</fo:simple-page-master>
</fo:layout-master-set>
<xsl:for-each select="ROWDATA/ROW">
<xsl:if test='BLOCKSEQUENCE=1'>
<xsl:call-template name="page"/>
</xsl:if>
</xsl:for-each>
</fo:root>
</xsl:template>
<xsl:template name="page">
<fo:page-sequence master-reference="A4-landscape">
<fo:flow flow-name="xsl-region-body">
<fo:block>
<fo:table text-align="left" table-layout="fixed" width="100%">
<fo:table-column column-width="0.19cm"/>
<fo:table-column column-width="1.80cm"/>
<fo:table-column column-width="4.00cm"/>
<fo:table-column column-width="2.7cm"/>
<fo:table-column column-width="3.10cm"/>
<fo:table-column column-width="2.80cm"/>
<fo:table-column column-width="0.2cm"/>
<fo:table-column column-width="1.70cm"/>
<fo:table-column column-width="1.10cm"/>
<fo:table-column column-width="0.2cm"/>
<fo:table-column column-width="0.02cm"/>
<fo:table-column column-width="0.9cm"/>
<fo:table-column column-width="0.01cm"/>
<fo:table-column column-width="2.4cm"/>
<fo:table-column column-width="3.7cm"/>
<fo:table-column column-width="0.9cm"/>
<fo:table-column column-width="2.4cm"/>
<fo:table-body>
<xsl:call-template name="pageHeader"/>
//Here is my problem. I don't know how to call the pageBlock template the appropriate number of times.
<xsl:call-template name="pageBlock"/>
<xsl:call-template name="pageFooter"/>
</fo:table-body>
</fo:table>
</fo:block>
</fo:flow>
</fo:page-sequence>
</xsl:template>
Cheers
Tom
Philosophy: The art of never getting beyond the concept of life.
Religion: Morality taking credit for the work of luck.
|
|
|
|
|
Your XML was not valid so I used the following:
<?xml version="1.0" ?>
<ROWDATA>
<ROW>
<TABLE_ROW_DETAILS>XSL-FO to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>1</BLOCKSEQUENCE>
</ROW>
<ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>2</BLOCKSEQUENCE>
</ROW>
<ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>3</BLOCKSEQUENCE>
</ROW>
<ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>1</BLOCKSEQUENCE>
</ROW>
<ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>2</BLOCKSEQUENCE>
</ROW>
<ROW>
<TABLE_ROW_DETAILS>to describe the row of a table</TABLE_ROW_DETAILS>
<BLOCKSEQUENCE>1</BLOCKSEQUENCE>
</ROW>
</ROWDATA>
For illustration, I transformed this XML to HTML into 3 sets of tables. The key to the
transformation is to get the first following sibling of ROW "following-sibling::ROW[1]" and the "blocksequence" parameter that stops the recursion when BLOCKSEQUENCE does not equal it.
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="ROWDATA/ROW[BLOCKSEQUENCE = 1]" mode="page"/>
</body>
</html>
</xsl:template>
<xsl:template match="ROW" mode="page">
<table class="page">
<xsl:apply-templates select="." mode="row">
<xsl:with-param name="blocksequence" select="1"/>
</xsl:apply-templates>
</table>
</xsl:template>
<xsl:template match="ROW" mode="row">
<xsl:param name="blocksequence"/>
<xsl:if test="$blocksequence = BLOCKSEQUENCE">
<tr>
<td><xsl:value-of select="BLOCKSEQUENCE"/><xsl:text>: </xsl:text></td>
<td><xsl:value-of select="TABLE_ROW_DETAILS"/></td>
</tr>
<xsl:apply-templates select="following-sibling::ROW[1]" mode="row">
<xsl:with-param name="blocksequence" select="$blocksequence + 1"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Output:
<html>
<body>
<table class="page">
<tr>
<td>1: </td>
<td>XSL-FO to describe the row of a table</td>
</tr>
<tr>
<td>2: </td>
<td>to describe the row of a table</td>
</tr>
<tr>
<td>3: </td>
<td>to describe the row of a table</td>
</tr>
</table>
<table class="page">
<tr>
<td>1: </td>
<td>to describe the row of a table</td>
</tr>
<tr>
<td>2: </td>
<td>to describe the row of a table</td>
</tr>
</table>
<table class="page">
<tr>
<td>1: </td>
<td>to describe the row of a table</td>
</tr>
</table>
</body>
</html>
"We make a living by what we get, we make a life by what we give." --Winston Churchill
-- modified at 16:27 Monday 17th September, 2007
|
|
|
|
|
Thanks George
Cheers
Tom
Philosophy: The art of never getting beyond the concept of life.
Religion: Morality taking credit for the work of luck.
"The object of life is not to be on the side of the majority, but to escape finding oneself in the ranks of the insane."
- Marcus Aurelius
|
|
|
|
|
Hello All,
I am having issues trying to convert XML to HTML using C#. I have done this before using simple style sheets and simple xml documents.
I now have to do this on a larger scale.
The current issue is that I get an XsltException stating 'matches()' is an unknown XSLT function. This exception is thrown on the xslCompiledTransform.transfrom call.
Is this a standard function? If so how do I use it?
If anyone can help me with this I would greatly appreciate it.
My code snippet.
String outputFile = outputFileTextBox.Text;
XmlUrlResolver resolver = new XmlUrlResolver();
XslCompiledTransform tran = new XslCompiledTransform(true);
tran.Load(new XPathDocument(xsltFileTextBox.Text), XsltSettings.Default, resolver);
tran.Transform(xmlInTextBox.Text, outputFile);
Thanks in advance for all the help.
Phillippio
|
|
|
|
|
|
George,
Thank you very much for this information. It is very helpful.
Have you every used either of these 2 with c#?
Thanks Again
Phillippio
|
|
|
|
|
Actually, I only use C# when I have too. I do most of my programming in C++/CLI, and I have used both in C++/CLI.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
Hello,
VS 2005
I am using a dataset to write to an xml file using the following
dim dsIncidents as new Dataset()
dsIncidents.WriteXML(xmlIncidentFile, XmlWriteMode.DiffGram)
I use a different dataset to read the xml file
dim dsReadIncidents as new Dataset()
dsReadIncidents(xmlIncidentFile,XmlReadMode.DiffGram) 'When I check the number of tables, there is zero.
However, if I do the following without using the DiffGram it works ok, and I can read the xml file and display the table.
dsIncidents.WriteXML(xmlIncidentFile)
dsReadIncidents(xmlIncidentFile)
Now it will read in the xml file. But I need to read in the DiffGram as I need to track changes to the dataset.
Can anyone tell me what could be the problem in reading and writing using the DiffGram.
Many thanks for any suggestions,
Steve
|
|
|
|
|
Hello Friends ,
I am new in xml , i want use xml as database like sqlserver. how can i
fire insert ,update ,delete command for xml database .
Manu
|
|
|
|
|
Hi,
I am creating an in-memory xml file using XMLDOM.
Does this xml file need to be formatted with CRLFs so that each node is on a new line or does the file as a single line with all the nodes make a difference?
The file has been formatted properly, with begin and end tags but the fact it is saved as one line make a difference?
I feel that it should not make a difference as long as all the tags are set up properly.
For example:
With breaks:
<person>
<lname></lname>
<fname></fname>
<address>/address>
</person>
Without breaks
<person><lname></lname><fname></fname><address>/address></person>
Many thanks.
|
|
|
|
|
Either format is okay! However, the format without breaks loads and parses faster, saves disk space, and possibly some memory. By the way, if you want to make your XML file even smaller, use attributes wherever possible.
"We make a living by what we get, we make a life by what we give." --Winston Churchill
|
|
|
|
|
I'm working on an XML schema for defining flat file layouts. I will be converting our current, template based[1] defintions to XML definitions, and was wondering about how best to express the options for the content of a column in a flat file, especially for exports, i.e. producing the file.
I'm looking at a sequence of Column[2] elements, where each Column element has a name, and a value source. Currently, the value sources are only ADO.NET columns in a data source, or literals. I would however like to expand the potential value sources to include functions etc.
My main concern is how to express the choice of value source. I'll use {} instead of angle brackets to show what I mean. My Column element would look something like:
{Column name="CustomerID" type="System.Int32"}
{DataField query="Customers" field="CustomerNo" /}
{Lookup table="xxx" ..... /}
{Literal}999{/Literal}
{/Column}
I could just use a literal value as a text node below the Column element, but that breaks consistency with the other content types. What suggestions can I get for expressing this?
[1] It is currently a very hard to maintain system where a record layout is defined as s string, with tabs, commas, etc. between output columns. If a non-delimiter string is surrounded by '%' characters, it is the name of a field from the data source to render into that column.
I do not believe they are right who say that the defects of famous men should be ignored. I think it is better that we should know them. Then, though we are conscious of having faults as glaring as theirs, we can believe that that is no hindrance to our achieving also something of their virtues. - W. Somerset Maugham
My New Blog
|
|
|
|
|
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.
|
|
|
|