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
Post a Comment