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

design - Custom Styling Qt Quick Controls -

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