 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

January 28th, 2010, 12:41 PM
|
|
Authorized User
|
|
Join Date: Jan 2010
Posts: 32
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
No this command line tool does not allow me to give a stylesheet parameter.
It only takes three arguements. input document Stylesheet doc outputdoc.
|
|

January 28th, 2010, 12:42 PM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
|
|
The above works fine for me.
Is there anything different with the actual files compared to the ones you've posted? Specifically has the second file got a namespace? Because that would cause the problem you are seeing.
|
|

January 28th, 2010, 12:47 PM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Quote:
Originally Posted by cooltechie
The Result I am getting is the same Input document that I am providing.
I am not seeing the Newfield Elements being added to the resulting output.
I have my input XML, xsl and the document that I am pointing to use document function, and the commandline tool all saved in the same directory.
so I am using this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:output encoding="UTF-8" method="xml"/>
<xsl:param name="dataurl" select="'book.xml'"/>
<xsl:variable name="bookdata" select="document($dataurl)"/>
<xsl:param name="dataurl" select="'book.xml'"/>
<xsl:variable name="bookdata" select="document($dataurl)"/>
<xsl:output indent="yes"/>
<xsl:key name="k1" match="book" use="ID"/>
<xsl:template match="/|@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="book">
<xsl:variable name="id" select="ID"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:for-each select="$bookdata/book">
<xsl:apply-templates select="key('k1', $id)/*[starts-with(local-name(), 'NewField')]"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="NewField">
<NewField>
<xsl:value-of select="."/>
</NewField>
</xsl:template>
</xsl:stylesheet>
|
So you have changed the stylesheet I posted. For instance
<xsl:for-each select="$bookdata/book">
is not what I posted (I did <xsl:for-each select="$book-data">) and is not something that makes sense as the XML sample you posted does not have any root element named 'book'. And you don't need to access the root element, the for-each is simply a way to set the context node for the key function used inside.
The sample I posted works against the two input samples you posted, I am not sure why you changed them.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

January 28th, 2010, 12:50 PM
|
|
Authorized User
|
|
Join Date: Jan 2010
Posts: 32
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
sam,
Thanks for catching that..the second file that I was using with document function indeed had a namespace..I removed it but it still did not work.
|
|

January 28th, 2010, 12:51 PM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
|
|
The newest stylesheet you posted declares a key on the input document, then tries to search for these NewValue fields on it.
Also, XML is case sensitive. You keep using "book" rather than "Book".
Also, $bookdata/Book will return nothing, because Book is not the root element of the second document.
Code:
...
<xsl:param name="dataurl" select="'Input2.xml'"/>
<xsl:variable name="bookdata" select="document($dataurl)"/>
<xsl:template match="/|@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Book">
<xsl:variable name="id" select="ID"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:for-each select="$bookdata/Root/Book[ID=$id]">
<xsl:apply-templates select="*[starts-with(local-name(), 'NewField')]"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
...
|
|

January 28th, 2010, 12:55 PM
|
|
Authorized User
|
|
Join Date: Jan 2010
Posts: 32
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Hi Martin,
Sorry..about that I reverted back to what you posted for for-each to set the context for key. I am still not seeing the output I want...
|
|

January 28th, 2010, 01:04 PM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
Quote:
Originally Posted by cooltechie
Hi Martin,
Sorry..about that I reverted back to what you posted for for-each to set the context for key. I am still not seeing the output I want...
|
Namespaces matter when using XML, XSLT and XPath. If the second document has elements in a namespace then the stylesheet needs to be adjusted to take that namespace into account.
So assuming you have
Code:
<Root xmlns="http://example.com/">...</Root>
in your second XML you need to adjust the stylesheet to e.g.
Code:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ex="http:/example.com/"
version="1.0">
<xsl:param name="book-url" select="'test2010012802.xml'"/>
<xsl:variable name="book-data" select="document($book-url)"/>
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="k1" match="ex:Book" use="ex:ID"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Book">
<xsl:variable name="id" select="ID"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:for-each select="$book-data">
<xsl:apply-templates select="key('k1', $id)/*[starts-with(local-name(), 'NewField')]"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I also have a feeling that the elements you want to add from your real XML are not named 'NewFieldSomething' but I am afraid we can only write code against the samples you present and can only find out why your attempts fail if you show the real input you have.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

January 28th, 2010, 01:05 PM
|
|
Authorized User
|
|
Join Date: Jan 2010
Posts: 32
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Hi sam,
I checked the cases, here on my computer code version the vers, they seem to be right. the input doc on my computer has a lower case for book. so I think we are good there.
But , i tried your new version:
<xsl:template match="book">
<xsl:variable name="id" select="ID"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:for-each select="$bookdata/Root/book[ID=$id]">
<xsl:apply-templates select="*[starts-with(local-name(), 'NewField')]"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
But still did not work.
|
|

January 28th, 2010, 01:15 PM
|
 |
Friend of Wrox
|
|
Join Date: Aug 2007
Posts: 2,128
Thanks: 1
Thanked 189 Times in 188 Posts
|
|
Hi
As Martin has already stated, using the input files you have given us our code works fine. Therefore there is a difference between the files you are actually using and the ones you are posting here.
Without understanding what those differences are it is hard to guess what the issue might be - the two most likely, namespaces and case sensitivity have just been covered.
|
|

January 28th, 2010, 01:17 PM
|
|
Authorized User
|
|
Join Date: Jan 2010
Posts: 32
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Hi Martin,
Thank you for the explanation: Here is what I have so far:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.xxx.com/"
>
<xsl:output encoding="UTF-8" method="xml"/>
<xsl:param name="dataurl" select="'books.xml'"/>
<xsl:variable name="bookdata" select="document($dataurl)"/>
<xsl:key name="k1" match="book" use="ID"/>
<xsl:template match="/|@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="book">
<xsl:variable name="id" select="ID"/>
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:for-each select="$bookdata">
<xsl:apply-templates select="key('k1', $id)/*[starts-with(local-name(), 'NewField')]"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="NewField1">
<DateClosed>
<xsl:value-of select="."/>
</DateClosed>
</xsl:template>
</xsl:stylesheet>
Structure of the second input doc:
<books xmlns=" xmlns="http://www.xxx.com/">
<book>
<ID>1</ID>
<NewField1>2007-10-01T00:00:00.000</NewField1>
<NewField2>2007-10-01T00:00:00.000</NewField2>
<NewField3>2007-10-01T00:00:00.000</NewField3>
</book>
<book>
<ID>2</ID>
<NewField1>2007-10-01T00:00:00.000</NewField1>
<NewField2>2007-10-01T00:00:00.000</NewField2>
<NewField3>2007-10-01T00:00:00.000</NewField3>
</book>
</books>
|
|
 |