|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Image A - Before transformation
Image B - After transformation IntroductionThis article describes a means of using C# to create a node-tree-fragment in XSLT. OverviewThe concept derives from embedding well-formed XML inside an existing XML object programmatically, by setting the inner text portion of a given element. I could have used an XML DOM append child node technique, but for the purposes of this example, I chose not to. When you do this, the embedded well-formed XML is treated as a string, not as XML nodes. Image A shows the embedded XML in black color. You cannot expand or collapse any of the embedded XML nodes. Several solutions that I have found required me to use a different XML parser other than what is provided via Microsoft - Xerces comes to mind. In fact, the Microsoft XML parser does not include a native function for converting strings to node-tree-fragments. So, how can you access the values or the elements? A conversion of the XML string to a node tree fragment needs to take place. The problem: I needed to embed XML within XML. Afterwards, a transformation from one XML format to another is performed. Embedding XML within XML is a practice not recommended by various XML pundits. However, when the situation cannot be modified such that a best-practices approach can occur, there is not a whole lot one can do. Enter IE XML/XSLT node-tree-fragment creation using the .NET Framework! Using the codeThe real trick is setting up the XSLT file with the appropriate namespaces: <xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:cs="urn:the-xml-files:xslt-csharp"
exclude-result-prefixes="cs ms">
Once the namespace declarations have been set, adding any number of .NET Framework aware classes is relatively easy. I use the <ms:script language="C#" implements-prefix="cs">
<![CDATA[
XPathNodeIterator parse(String strXML)
{
System.IO.StringReader rdr = new System.IO.StringReader(strXML);
XPathDocument doc = new XPathDocument(rdr);
XPathNavigator nav = doc.CreateNavigator();
XPathExpression expr;
expr = nav.Compile("/");
XPathNodeIterator iterator = nav.Select(expr);
return iterator;
}
]]>
</ms:script>
Here is a sample XML snippet. Note the <request>
<tkrnum>300005</tkrnum>
<zertnum>20010003</zertnum>
<username>DIRENZO</username>
<result>implemented</result>
<system_codes>Embedded Well-Formed XML is here - download
article source to see it</system_codes>
</system_codes>
</request>
Here is the XSL code snippet that accesses the <xsl:variable name="syscodes" select="cs:parse(system_codes)"/>
<internal_sys_codes>
<!-- Iterate here-->
<xsl:for-each select="$syscodes//trresult" >
<sys_code>
<icode><xsl:value-of select="srdcode"/></icode>
<icomment><xsl:value-of select="comment"/></icomment>
</sys_code>
</xsl:for-each>
</internal_sys_codes>
Note the Points of InterestThe real crux of this technique is that it cannot be performed unless we do a server-side transform. The transform must be done with the .NET Framework, or an Invalid class string exception is thrown. Simply referencing the XSL file within the XML file will not work. See Image B for the results of the transformation.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||