By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,247 Members | 1,018 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,247 IT Pros & Developers. It's quick & easy.

Multiple External References in Transfom

P: n/a
Having worked through the problems around enabling the document function
using an XmlUrlResolver I started work on building a useful class to hide
the intricacies.
Trying to generalise the process I've hit a snag.

How do I resolve multiple external references?

The transform method on a stylesheet only takes one resolver, not an array

Stephen
Nov 12 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Stephen Cook wrote:
How do I resolve multiple external references?

The transform method on a stylesheet only takes one resolver, not an array


What do you mean? Resolver object is supposed to resolve all external
references, not a single one.
--
Oleg Tkachenko
XML Insider
http://www.tkachenko.com/blog

Nov 12 '05 #2

P: n/a
Aha!

Question becomes - How do I create multiple references within one resolver?

Stephen

"Oleg Tkachenko" <oleg@NO!SPAM!PLEASEtkachenko.com> wrote in message
news:eG**************@TK2MSFTNGP12.phx.gbl...
Stephen Cook wrote:
How do I resolve multiple external references?

The transform method on a stylesheet only takes one resolver, not an
array
What do you mean? Resolver object is supposed to resolve all external
references, not a single one.
--
Oleg Tkachenko
XML Insider
http://www.tkachenko.com/blog

Nov 12 '05 #3

P: n/a
Long post - Posted to explain the background to the issue of resolvers,
highlight a couple of further points around evidences and resolution of
paths and hopefully provide a full example that is useful by way of
returning a little of the help I continue to receive from these sort's of
resources.

A bit of background for the casual reader.

The object of the exercise was to create a class that would create a regular
data island (no null attributes) from the output of SQLXML.
This is structured to support the built-in table binding of internet
explorer.

The following example is from my scratch routine, built while I explored the
..Net framework's XML library.
The output stream strmOutput is created externally.
You might use something like

XmlTextWriter writer = new XmlTextWriter(Console.Out);
writer.Formatting=Formatting.Indented;
or
XmlTextWriter xtwDump = new
XmlTextWriter("C:\\dumpXslTest.xml",System.Text.En coding.UTF8);
xtwDump.Formatting = Formatting.Indented;

in the web environment, to generate the data island use something like
strmOutput = new
StreamWriter(HttpContext.Current.Response.OutputSt ream,System.Text.Encoding.
UTF8,640);

Anyway all that stuff gets set up in the public methods before calling the
following
(Rest of routine needs re-factoring as presented here, but easier to explain
in one routine)

private Boolean prvTransformDataset()
{
string strConn = "Database Connection";
// Reference to stylesheet to convert raw XMl into "regular" xml data
island that can be consumed by internet explorer's

table binding
string stylesheet =
"C:\\projects\\projectfolder\\BusinessObject\\gene ral.xslt"; //Point A
below

try
{
//Get the raw XML data
SqlXmlCommand cmd = new SqlXmlCommand(strConn);
cmd.RootTag = "XML";
cmd.CommandText = "Select * from tablename for xml auto";
cmd.CommandType = SqlXmlCommandType.Sql;
XmlReader xReader = cmd.ExecuteXmlReader();

//Load into a suitable document
XPathDocument xpathdocument = new
XPathDocument(xReader,XmlSpace.Preserve);

//Now set up the transform
XslTransform xslt = new XslTransform();
//Transform includes an external reference to a simplifed schema for the
output table
//Which is loaded as a variable in the stylesheet
//<xsl:variable name="Sch"
select="document('C:/projects/projectfolder/BusinessObject/tableschema.xml')
" />
XmlUrlResolver xrsSchema = new XmlUrlResolver();
Uri uriSchema = new Uri(stylesheet);
Uri uriFull = xrsSchema.ResolveUri(uriSchema,"tableschema.xml");
xslt.Load(stylesheet); //Point B below

//Create an XsltArgumentList to pass in the parameterised tags
// A bindable data island has three levels
XsltArgumentList xslArg = new XsltArgumentList();
xslArg.AddParam("Island","", "dsoTableNameId");
xslArg.AddParam("Group","", "CollectionName");
xslArg.AddParam("Line","", "Data");

//Now ready to perform the transform
// Finally worked when I included the reference to the resolver here
rather than at stylesheet load
// I don't understand what causes the difference (I make mistakes??)
xslt.Transform(xpathdocument, xslArg, strmOutput, xrsSchema);
// Make sure we get the whole thing - Again this didn't appear to be
necessary.
strmOutput.Flush();
return(true);
}
catch(Exception e)
{
XmlTextWriter txwError = new XmlTextWriter(Console.Error);
txwError.WriteRaw(("Error in try" + e.ToString()));
return(false);
}
finally
{
//Lots of tidy up in here
}
}

Point A.

This is the full transform (well something like it anyway)
This variant generates the data as attributes. It's not hard to convert to
generate data as tags (exercise for the reader)
Note that there is no namespace handling in here
All null attributes are generated
and all dates are translated in to a more human-friendly format

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xsl xs"
version="1.0">

<xsl:output method="xml" indent="yes"/>

<xsl:param name="Island" select="'islandId'"/>
<xsl:param name="Group" select="'collection'"/>
<xsl:param name="Line" select="'data'"/>
<xsl:variable name="Sch"
select="document('C:/projects/projectfolder/BusinessObject/tablename.xml')"
/>

<!--Match the root node -->
<xsl:template match="/">
<xsl:element name="xml">
<xsl:attribute name="id">
<xsl:value-of select="$Island"/>
</xsl:attribute>
<xsl:element name="{$Group}">
<xsl:apply-templates select="*|@*"/>
</xsl:element>
</xsl:element>
</xsl:template>

<!-- Match each data row -->
<xsl:template match="//tablename"> <!-- this could be a parameter too -->
<xsl:element name="{$Line}">
<!-- store this row in a variable -->
<xsl:variable name='row' select='.'/>
<!-- iterate through each field (from the s:Schema section) -->
<xsl:for-each
select="$Sch/xs:schema/xs:element[@name='lps_location']/xs:complexType/xs:at
tribute">

<xsl:choose>
<!-- test for date time fields to permit extra conversion -->
<xsl:when test="@type='xs:dateTime'">
<!-- copy the name of this field into a variable -->
<xsl:variable name='fieldname' select='@name'/>
<!-- output the element, and the data value as attribute-->
<xsl:attribute name='{$fieldname}'>
<!-- xsl:value-of select='$row/@*[name()=$fieldname]'/ -->
<xsl:variable name="datevalue" select='$row/@*[name()=$fieldname]'/>
<xsl:if test="$datevalue!=''">
<xsl:value-of select="substring($datevalue,9,2)"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="substring($datevalue,6,2)"/>
<xsl:text>/</xsl:text>
<xsl:value-of select="substring($datevalue,1,4)"/>
<xsl:text> </xsl:text>
<xsl:value-of

select="substring(substring-after($datevalue,'T'),1,8)"/>
</xsl:if>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<!-- copy the name of this field into a variable -->
<xsl:variable name='fieldname' select='@name'/>
<!-- output the element, and the data value as attribute -->
<xsl:attribute name='{$fieldname}'>
<xsl:value-of select='$row/@*[name()=$fieldname]'/>
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>

</xsl:for-each>
</xsl:element>
</xsl:template>

</xsl:transform>

My schema looked somehing like this - you can see I was reading some
addressing data
Only the "required" fields appear by default from SQLXML.
If the values for the any of the other fields are null in the database, no
attribute is generate by SQLXML, so we want to add it.

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="SGC">
<xs:complexType>
<xs:sequence>
<xs:element ref="lps_location" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="lps_location">
<xs:complexType>
<xs:attribute name="LOCATION_ID" type="xs:short" use="required"/>
<xs:attribute name="INITIAL_LOCATION_ID" type="xs:short" use="required"/>
<xs:attribute name="PREDECESSOR_ID" type="xs:short" use="required"/>
<xs:attribute name="BUILDING" type="xs:string"/>
<xs:attribute name="ROAD" type="xs:string"/>
<xs:attribute name="DISTRICT" type="xs:string"/>
<xs:attribute name="CITY" type="xs:string"/>
<xs:attribute name="COUNTY" type="xs:string"/>
<xs:attribute name="ACTIVE" type="xs:string" use="required"/>
<xs:attribute name="CREATED_BY" type="xs:string" use="required"/>
<xs:attribute name="CREATED_DATE" type="xs:dateTime" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
Point B.

I couldn't get any joy from using the overloaded "Load" method
(stylesheet,resolver).
Perhaps this is used to resolve the "xsl:import" and "xsl:include"
references????
Note that such an overload is now deprecated and advice appears to be to use
(stylesheet, resolver, evidence)
I didn't get a great deal of joy from evidence either.
Lots of confusion (for me) around http examples, where I was staying in the
middle tier and doing direct file access

I also found that having created this resolver I was getting good data from
both the identifed path and from "C:\tablename.xml".
The resolver would "fail" for files of different names, but still let
through a file of the same name on either path.
I didn't expect this.
I would have thought that only the exact path I entered would be valid, not
any path in the same domain(???)
I haven't tested in more detail. Perhaps this is a case for sorting out a
credentials object or the evidence object???
Nov 12 '05 #4

P: n/a
Hi Stephen,

I'm currently researching on this issue and will update you as soon as I
get any progress.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 12 '05 #5

P: n/a
I assume your interested in the behaviour of the resolver.
Contact me directly if the full working example would be useful, rather than
the slightly mangled version presented here.

Many thanks for your interest

Stephen

"Kevin Yu [MSFT]" <v-****@online.microsoft.com> wrote in message
news:ms**************@cpmsftngxa06.phx.gbl...
Hi Stephen,

I'm currently researching on this issue and will update you as soon as I
get any progress.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 12 '05 #6

P: n/a
Hi Stephen,

We need to use the XmlResolver at different time based on different
situation. For example, to resolve with Document () function, we have to
use it with Transform function. For more information on this issue, you may
refer to:

http://msdn.microsoft.com/library/de...us/cpguide/htm
l/cpconresolvingexternalxsltstylesheetsdocuments.asp

Luke
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)

Nov 12 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.