c# - Transforming repeating group into several text lines -


i wanted transform repeating group sample xml 2 delimited text lines. here current code version:

string orderxml =  @"<?xml version='1.0' encoding='utf-8'?> <order id='79223510'> <status>new</status> <shipmethod>standard international</shipmethod> <tocity>tokyo</tocity> <items>     <item>     <sku>sku-1234567890</sku>     <quantity>1</quantity>     <price>99.95</price>     </item>     <item>     <sku>sku-1234567899</sku>     <quantity>1</quantity>     <price>199.95</price>     </item> </items> </order>";  stringreader str = new stringreader(orderxml);  var xslt = new xmltextreader(new stringreader( @"<?xml version='1.0' encoding='utf-8'?>" + "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/xsl/transform'>" +  "<xsl:output method='text' indent='no'/>" +  "<!-- new line character variable -->" + "<xsl:variable name='newline'>" + "<xsl:text>&#13;&#10;</xsl:text>" + "</xsl:variable>" + "<xsl:variable name='empty'>" + "<xsl:text></xsl:text>" + "</xsl:variable>" +  "<xsl:template match='/'>" +           "<xsl:for-each select='order'>" + "<xsl:value-of select='@id'/>|" +  "<xsl:value-of select='status'/>|" + "<xsl:value-of select='shipmetod'/>|" + "<xsl:value-of select='tocity'/>|" +  "<xsl:value-of select='$newline'/>" + "</xsl:for-each>" +  "<xsl:for-each select='order/items/item'>" + "<xsl:value-of select='sku'/>|" +           "<xsl:value-of select='quantity'/>|" +    "<xsl:value-of select='price'/>|" +     "<xsl:value-of select='$newline'/>" + "</xsl:for-each>" +   "</xsl:template>" + "</xsl:stylesheet>"                 ));  var xdoc = new xpathdocument(str); var xtr = new system.xml.xsl.xslcompiledtransform(); xtr.load(xslt);  stringbuilder sb = new stringbuilder(); stringwriter writer = new stringwriter(sb); xtr.transform(xdoc, null, writer);  string[] lines = sb.tostring().split(new string[] {"\n"}, stringsplitoptions.removeemptyentries);      lines.tolist().foreach(system.console.write);      

this code produces following output:

79223510|new||tokyo| sku-1234567890|1|99.95| sku-1234567899|1|199.95| 

and wanted produce following one:

79223510|new||tokyo|sku-1234567890|1|99.95| 79223510|new||tokyo|sku-1234567899|1|199.95| 

by using xsl transformation. please advise.

p.s. added xsl in text form easier reading:

@<?xml version='1.0' encoding='utf-8'?> <xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/xsl/transform'>  <xsl:output method='text' indent='no'/>  <!-- new line character variable --> <xsl:variable name='newline'> <xsl:text>&#13;&#10;</xsl:text> </xsl:variable> <xsl:variable name='empty'> <xsl:text></xsl:text> </xsl:variable>  <xsl:template match='/'>           <xsl:for-each select='order'> <xsl:value-of select='@id'/>|  <xsl:value-of select='status'/>| <xsl:value-of select='shipmetod'/>| <xsl:value-of select='tocity'/>|  <xsl:value-of select='$newline'/> </xsl:for-each>  <xsl:for-each select='order/items/item'> <xsl:value-of select='sku'/>|           <xsl:value-of select='quantity'/>|    <xsl:value-of select='price'/>|     <xsl:value-of select='$newline'/> </xsl:for-each>   </xsl:template> </xsl:stylesheet> 

you making few mistakes:

  1. you using 2 separate for-each loops rather loop in loop, first line of output order element, , next 2 item elements. (actually don't need loops. solution below.)
  2. you misspelled shipmetod, 1 of fields mistakenly blank.
  3. you don't have method in place escape | values may present in field values. (my solution doesn't solve problem since i'm not sure want it.)

a better solution use template matching , string-concatenation.

<xsl:stylesheet version="1.0" xmlns:xsl='http://www.w3.org/1999/xsl/transform'> <xsl:output method="text" indent="no" media-type="text/plain" />  <xsl:variable name='newline'><xsl:text>&#13;&#10;</xsl:text></xsl:variable> <xsl:variable name='delimiter'>|</xsl:variable>  <!-- default, don't copy nodes output --> <xsl:template match="node()|@*"><xsl:apply-templates select="node()|@*"/></xsl:template>  <xsl:template match="/order/items/item"><xsl:value-of select="concat( ../../@id, $delimiter, ../../status, $delimiter, ../../shipmethod, $delimiter, ../../tocity, $delimiter, sku, $delimiter, quantity, $delimiter, price, $delimiter, $newline)"/></xsl:template>  </xsl:stylesheet> 

this produces following output:

79223510|new|standard international|tokyo|sku-1234567890|1|99.95| 79223510|new|standard international|tokyo|sku-1234567890|1|199.95| 

Comments

Popular posts from this blog

c# - SVN Error : "svnadmin: E205000: Too many arguments" -

c# - Copy ObservableCollection to another ObservableCollection -

All overlapping substrings matching a java regex -