xml - Unexpected behavior with XSLT when trying to select first matching element -


i have data want serialize xml in specific format. have array of testclass, consists of 2 string properties: a , b.

i know doesn't sound practice, in case, expect values of a identical instances of testclass.

i want create xml file contains common a value , b values. i've written following code:

using system; using system.collections.generic; using system.linq; using system.text; using system.xml.serialization; using system.xml.xsl; using system.io;  namespace test {     public class program     {         public class testclass         {             public string { get; set; }             public string b { get; set; }         }          static void main(string[] args)         {             testclass[] array = new testclass[]             {                 new testclass() { = "a1", b="b1"},                 new testclass() { = "a2", b="b2"}             };              xmlserializer serializer = new xmlserializer(typeof(testclass[]));             xslcompiledtransform xslt = new xslcompiledtransform();                         xslt.load("test.xslt");              string xml1name = @"c:\temp\xmltest\original.xml";             string xml2name = @"c:\temp\xmltest\transformed.xml";                          using (filestream xmlstream = new filestream(xml1name, filemode.create))             {                 serializer.serialize(xmlstream, array);             }             xslt.transform(xml1name, xml2name);         }     } } 

test.xslt contains following:

<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"   xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" >    <xsl:template match="/arrayoftestclass/testclass[1]">     <test>       <a>         <xsl:value-of select="a"/>       </a>       <b_values>         <xsl:for-each select="/arrayoftestclass/testclass">           <value>             <xsl:value-of select="b" />           </value>         </xsl:for-each>       </b_values>     </test>   </xsl:template> </xsl:stylesheet> 

i expect code should output 2 files. "default" serialization generated xmlserializer class appears correct.

<?xml version="1.0"?> <arrayoftestclass xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:xsd="http://www.w3.org/2001/xmlschema">   <testclass>     <a>a1</a>     <b>b1</b>   </testclass>   <testclass>     <a>a2</a>     <b>b2</b>   </testclass> </arrayoftestclass> 

the xslt transformed xml correct, contains trailing text, appears values of a , b in second element of serialized array. not typo:

<?xml version="1.0" encoding="utf-8"?>   <test><a>a1</a><b_values><value>b1</value><value>b2</value></b_values></test>      a2     b2 

why xslt not generating result expect? how can make right?

this because of built-in templates of xslt, used in case xslt processor can't find specific template in stylesheet nodes trying match. built-in template elements , root node skip on element , templates match children. if finds text node, output text.

in xslt, not have template matching either / or arrayoftestclass element, , built-in templates kick-in. if case of arrayoftestclass templates match child nodes, have specific template matching first child node. other testclass elements matched built-in template, , text within them output.

all need add template tell xslt stop-processing other testclass elements. add template

<xsl:template match="/arrayoftestclass/testclass[position() > 1]" /> 

however, if ever going have testclass elements child nodes of arrayoftestclass elements, simplify this

<xsl:template match="testclass" /> 

this takes advantage of fact xslt give priority more specific template when multiple templates may match same element.


Comments

Popular posts from this blog

Unable to remove the www from url on https using .htaccess -