How to Use DataSource Property in DataFormWebPart - sharepoint-2007

I'm writing a custom web part that extends DataFormWebPart.
public class MyCustomWebPart : DataFormWebPart{
// other methods
public override void DataBind()
{
XmlDataSource source =
new XmlDataSource() { Data = #"
<Person>
<name cap='true'>Bryan</name>
<occupation>student</occupation>
</Person>
"
};
DataSources.Add(source);
base.DataBind();
}
}
The only noticeable thing I do is overriding the DataBind() method, where I use xml as the data source.
After I deploy the web part, I set the following XSL to it:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xmp>
<xsl:copy-of select="*"/>
</xmp>
</xsl:template>
</xsl:stylesheet>
This xsl will surround the input xml with a tag . So I expected the web part to display the original xml data as I wrote in C# code behind. But what shows up in the web part is this:
<Person>
<name cap="true" />
<occupation />
</Person>
All the values within the inner-most tags disappear.
What's going on? Can anybody help me?
Thanks.

I know this is several months since your question but I also experienced this same issue and have found the resolution.
On this MSDN forum post - http://social.msdn.microsoft.com/forums/en-US/sharepointdevelopment/thread/0a0527b6-3a05-4791-8cc5-9a6de07d23f3
they mentioned that there is a bug in the xsmldatasource xpath navigation binding, and the resolution is to override the GetXPathNavigator method.
moving code from the databind to this method immediately resolved the lookup issue.

Related

URL rewrite using Datapower Gateway

I'm trying to setup a URL rewrite using datapower. A request will come in from the customer in the following format - /products/{productid}/balance the {productid} will change for each customer and I need to change the format to be /balance/products/{productid} so that I don't need multiple context roots in Websphere. I have setup a MPGW but I am unable to put in the correct variables to change the request above which is supposed to be written in Perl (which I don't know) Can anyone help please?
If I got it correctly, ou need to create Policy with Request-Rule wich will contain XSL-transformation like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
extension-element-prefixes="dp"
exclude-result-prefixes="dp" >
<xsl:template match="/">
<xsl:variable name="originalUrl" select="dp:variable('var://service/URI')"/>
<xsl:variable name="productId" select="substring-before(substring-after($originalUrl, '/products/'), '/balance')"/>
<xsl:variable name="modifiedUrl" select="concat('/balance/products/', $productId)"/>
<!--Set your own destination host ofc-->
<dp:set-variable name="'var://service/routing-url'" value="concat('http://127.0.0.1', $modifiedUrl)"/>
</xsl:template>
</xsl:stylesheet>
var://service/URI is a readonly service variable which contains URL-path from HTTP request
var://service/routing-url is a writable service variable wich contains a URI for routing

how to decode base64Binary-to-string in xslt

Hi I am trying to convert my Base64 data to string in xslt but unable to do so.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:saxon="http://saxon.sf.net/">
<xsl:template match="Data">
<xsl:element name="fos1">
<xsl:value-of select="(saxon:base64Binary-to-string(
xs:base64Binary("Data"),
"UTF8"))"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
I have one xml file also where i have stored base64 data the looks like below code
<?xml version="1.0" encoding="UTF-8"?>
<Data>e1xydGYxXGZiaWRpc1xhbnNpXGFuc2ljcGcxMjUyXGRlZmYwXGRlZmxhbmcxMDMxXGRlZmxhbmdmZTEwMzFcZGVmdGFiNzA4e1xmb250dGJse1xmMFxmc3dpc3NcZnBycTJcZmNoYXJzZXQwIFZlcmRhbmE7fX0NClx2aWV3a2luZDRcdWMxXHBhcmRcbHRycGFyXGxhbmcyMDU3XGJcZjBcZnMyMCBGYXJlIFJ1bGVzXHBhcg0KXGIwXHBhcg0KXHBhcg0KXGIgUmVib29raW5nc1xwYXINClxwYXJkXGx0cnBhclxxalxiMCBCb29raW5nIGNoYW5nZXMgYWxsb3dlZCwgdXAgdG8gMzAgbWludXRlcyBwcmlvciB0byBkZXBhcnR1cmUsIGZvciBhIGZlZSBvZiBcYiBFVVIgNjAgLyBDSEYgNzkgLyBHQlAgNTQgLyBVU0QgODMgLyBDWksgMTY4MCAvIFNFSyA2MDAgLyBOT0sgNDkyIC8gUExOIDI3NiAvIEhVRiAxOTgwMFxiMCAgcGVyIHBlcnNvbiBhbmQgbGVnLCB3aGVyZSBhcHBsaWNhYmxlIHBsdXMgZGlmZmVyZW5jZSB0byBhY3R1YWwgZmxpZ2h0IGZhcmUuIENoYW5nZSBvZiB0YXJpZmYgb25seSBhbGxvd2VkIGludG8gbmV4dCBoaWdoZXIgY2F0ZWdvcnkgaWYgaW5pdGlhbCB0YXJpZmYgbm90IGF2YWlsYWJsZS4gSUYgVEhFIE5FVyBGQVJFIElTIExPV0VSIFRIQU4gVEhFIE9SR0lOQUwgT05FLCBOTyBSRUZVTkQgV0lMTCBCRSBHUkFOVEVELlxwYXINClxwYXINClxwYXJkXGx0cnBhclxiIENhbmNlbGxhdGlvbnNccGFyDQpcYjAgQ2FuY2VsbGF0aW9ucyBhcmUgbm90IGFsbG93ZWQuIEZhcmUgaXMgbm9uIHJlZnVuZGFibGUuIElOIENBU0UgT0YgTk9TSE9XLCBQQVggTVVTVCBQVVJDSEFTRSBBTiBFTlRJUkVMWSBORVcgVElDS0VUIC8gT1JJR0lOQUwgUEFJRCBBTU9VTlQgV0lMTCBOT1QgQkUgUkVGVU5ERUQvQ1JFRElURUQuXHBhcg0KXHBhcg0KXGIgTmFtZSBDaGFuZ2VzXHBhcg0KXGIwIE5hbWUgY2hhbmdlcyBhbGxvd2VkLCB1cCB0byAzMCBtaW51dGVzIHByaW9yIHRvIGRlcGFydHVyZSwgZm9yIGEgZmVlIG9mIFxiIEVVUiA2MCAvIENIRiA3OSAvIEdCUCA1NCAvIFVTRCA4MyAvIENaSyAxNjgwIC8gU0VLIDYwMCAvIE5PSyA0OTIgLyBQTE4gMjc2IC8gSFVGIDE5ODAwIFxiMCBwZXIgcGVyc29uIGFuZCBib29raW5nLCB3aGVyZSBhcHBsaWNhYmxlIHBsdXMgZGlmZmVyZW5jZSB0byBhY3R1YWwgZmxpZ2h0IGZhcmUuXHBhcg0KXHBhcg0KXGIgQ2hlY2tlZCBMdWdnYWdlXHBhcg0KXGIwIENoZWNrZWQgbHVnZ2FnZSBvcHRpb25hbCwgc3RhbmRhcmQgYWRkaXRpb25hbCBjb3N0cyBhcHBseS5ccGFyDQpcYiBBVFROISBTbWFydDpcYjAgIE9uZSBwaWVjZSBvZiBjaGVja2VkIGx1Z2dhZ2UgaXMgYXV0b21hdGljYWxseSBpbmNsdWRlZCBwZXIgcGVyc29uICh0b3RhbCB3ZWlnaHQgMjMga2cpLCBmb3IgZnVydGhlciBwaWVjZXMgYW5kIGV4Y2VzcyBsdWdnYWdlLCBzdGFuZGFyZCBhZGRpdGlvbmFsIGNvc3RzIGFwcGx5LlxwYXINClxwYXINClxiIFNlYXRpbmdccGFyDQpcYjAgT3B0aW9uYWwsIHN0YW5kYXJkIGFkZGl0aW9uYWwgY29zdHMgYXBwbHkuXHBhcg0KXGIgQVRUTiEgU21hcnQ6IFxiMCBTZWF0IHJlc2VydmF0aW9uIGlzIGluY2x1ZGVkIHBlciBQZXJzb24sIGFsc28gbW9yZSBsZWdyb29tIHNlYXQgKGlmIGF2YWlsYWJsZSlcYlxwYXINClxiMFxwYXINClxiIE1pbGVzXHBhcg0KXGIwIEluY2x1ZGluZyBtaWxlc1xwYXINClxwYXINClxiIE1lYWxccGFyDQpcYjAgTm90IGluY2x1ZGVkXHBhcg0KXGIgQVRUTiEgU21hcnQ6IFxiMCBTbmFjayBhbmQgZHJpbmsgaW5jbHVkZWRccGFyDQpccGFyDQpccGFyDQpcYiBBVFROISEgRm9yIEJsaW5kIEJvb2tpbmcgRmFyZXMgYW5kIEJvb21lcmFuZyBSZXdhcmQgZmxpZ2h0cyB0aGUgcGFydGljdWxhciBjb25kaXRpb25zIGFjY29yZGluZyB0byBHZXJtYW53aW5ncyBHQ0MgYXBwbHkuXHBhcg0KXHBhcg0KfQ0K</Data>
The call xs:base64Binary("Data") tries to create a base-64 value from the character string "Data", which is not a legal base-64 string. So you should be getting an error message saying roughly that. Hmm. You didn't mention an error message; you didn't explain what exactly you mean by "unable to do so". Next time, provide more information, ok?
If you want to apply the function to the string value of the Data element, bear in mind that you are making the call in an expression located in a template which matches that element. You almost certainly want to replace the call in the current expression with something like xs:base64Binary(.).

Only element in xslt result set is not the last element?

I have the following snippet
<xsl:for-each select="book">
<xsl:value-of select="title"/><xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
I want it to be a list of comma-separated book titles.
The output is correct when I have no books in the list. It is also correct when I have more than one book.
However, if I have exactly one book, it prints a comma at the end.
When I change the condition to only print a comma if it is the last element, the case where there is only one book doesn't print a comma.
So it seems like when there is only one element it is not treated as the last element. How can I deal with this?
Sample XML: looks something like this
<booklist>
<book>
<title>My book</title>
<author>Some author</author>
</book>
<book>
<title>Another book</title>
<author>Another author</author>
</book>
</booklist>
When there are two books in the list, I get
My book, Another book
When I delete the second entry, I get
My book,
EDIT:
I found the issue. I was using an <xsl:apply-templates> to select a set of data, and then inside another template for each book, I was doing the position check. However, last() was referring to the original set of data and not the filtered subset.
The following works fine for me in Firefox (I get no commas for no books, and n-1 commas for n books if n>0). I suspect your XSLT processor is broken.
The XSLT ("x.xsl"):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" encoding="iso-8859-1" media-type="text/xhtml" doctype-public="-//W3C//DTD HTML 4.0//EN"/>
<xsl:template match="/">
<xsl:for-each select="root/book">
<xsl:value-of select="title"/><xsl:if test="position() != last()">;</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
The XML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="x.xsl" type="text/xsl"?>
<root>
<book>
<title>A</title>
</book>
<book>
<title>B</title>
</book>
</root>
What's "test()"? I think you want "last()-1".

Difference in template rule processing XSLT 1.0 vs 2.0 (bis)

See Diff 1.0 vs 2.0. That one is solved, but it is still a bit of a mystery to me what caused the issue in the first place.
Now I may have found something, but need help understanding what is going on.
I simplified the input xml to
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Manager>
<Employee grade="9"/>
<Employee grade="8"/>
</Manager>
<Manager>
<Employee grade="9"/>
<Employee grade="8"/>
<Employee grade="4"/>
</Manager>
</root>
The stylesheet I apply on this input is
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="root/Manager"/>
</root>
</xsl:template>
<xsl:template match="Manager">
<test><xsl:value-of select="Employee/#grade"/></test>
</xsl:template>
</xsl:stylesheet>
The output is
<?xml version="1.0" encoding="UTF-8"?>
<root>
<test>9</test>
<test>9</test>
</root>
But running the transformation in XSLT 2.0 mode (change stylesheet/#version to "2.0"), the output is
<?xml version="1.0" encoding="UTF-8"?>
<root>
<test>9 8</test>
<test>9 8 4</test>
</root>
I wonder what precise difference in XSLT 1.0 and XSLT 2.0 causes this.
Well for the first difference I did explain that with XSLT 2.0 the comparison operators like less than or greater than or less than or equal and so on by default compare strings while with XSLT 1.0 these operators are only defined for numbers and that way convert any operands to numbers.
For this post the difference is simply that with XSLT 1.0 xsl:value-of select="foo" outputs the string value of the first foo element in the selected node set of foo elements while with XSLT 2.0 this has changed, if a sequence is selected then a space separated list of the string value of item in the sequence is output. You can change the separator (i.e. space) used with the separator attribute of xsl:value-of in XSLT 2.0. See also http://www.w3.org/TR/xslt20/#incompatibilities.

How can I get xslt to indent xml (from Ant)?

From what I understand having looked around for an answer to this the following should work:
<xslt basedir="..." destdir="..." style="xslt-stylesheet.xsd" extension=".xml"/>
Where xslt-stylesheet.xsd contains the following:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Unfortunately while most formatting is applied (spaces are stripped, newlines entered, etc.), indentation is not and every element is along the left side in the file. Is this an issue with the xslt processor Ant uses, or am I doing something wrong? (Using Ant 1.8.2).
It might help to set some processor-specific output options, though you should note that these may vary depending on the XSLT processor that you're using.
For example, if you're using Xalan, it defines an indent-amount property, which seems to default to 0.
To override this property at runtime, you can declare xalan namespace in your stylesheet and override using the processor-specific attribute indent-amount in your output element as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xalan="http://xml.apache.org/xalan">
<xsl:output method="xml"
encoding="UTF-8"
indent="yes"
xalan:indent-amount="2"/>
This example is from the Xalan usage patterns documentation at http://xml.apache.org/xalan-j/usagepatterns.html
If you do happen to be using Xalan, the documentation also says you can change all of the output preferences globally by setting changing the file org/apache/serializer/output_xml.properties in the serializer jar.
In the interest of completeness, the complete set of Xalan-specific xml output properties defined in that file (Xalan 2.7.1) are:
{http://xml.apache.org/xalan}indent-amount=0
{http://xml.apache.org/xalan}content-handler=org.apache.xml.serializer.ToXMLStream
{http://xml.apache.org/xalan}entities=org/apache/xml/serializer/XMLEntities
If you're not using Xalan, you might have some luck looking for some processor-specific output properties in the documentation for your XSLT processor
Different XSLT processors implement indent="yes" in different way. Some indent properly, while others only put the element starting on a new line. It seems that your XSLT processor is among the latter group.
Why is this so?
The reason is that the W3C XSLT Specification allows significant leeway in what indentation could be produced:
"If the indent attribute has the value yes, then the xml output
method may output whitespace in addition to the whitespace in the
result tree (possibly based on whitespace stripped from either the
source document or the stylesheet) in order to indent the result
nicely; if the indent attribute has the value no, it should not
output any additional whitespace. The default value is no. The xml
output method should use an algorithm to output additional whitespace
that ensures that the result if whitespace were to be stripped from
the output using the process described in [3.4 Whitespace Stripping]
with the set of whitespace-preserving elements consisting of just
xsl:text would be the same when additional whitespace is output as
when additional whitespace is not output.
NOTE:It is usually not safe to use indent="yes" with document types that include element types with mixed content."
Possible solutions:
Start using another XSLT processor. For example, Saxon indents quite well.
Remove the <xsl:strip-space elements="*"/> directive. If there are whitespace-only text nodes in the source XML, they would be copied to the output and this may result in a better-looking indented output.
I don't know if ant is OK. But concerning your XSLT :
When you use the copy-of on an element, your XSLT processor does not indent. If you change your XSLT like this, your XSLT processor will may be manage to indent :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This XSLT will go through the whole XML tree and indents each element it creates.
EDIT after comment :
You can see the following question to change your XSLT processor, maybe it will solve your problem : How to execute XSLT 2.0 with ant?
You can try adding the {http://xml.apache.org/xslt}indent-amount output property in ant, something like this:
<target name="applyXsl">
<xslt in="${inputFile}" out="${outputFile}" extension=".html" style="${xslFile}" force="true">
<outputproperty name="indent" value="yes"/>
<outputproperty name="{http://xml.apache.org/xslt}indent-amount" value="4"/>
</xslt>
</target>

Resources