[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 599
  • Last Modified:

Wrong xml output with xslt transform in c# code vs. xmlspy

My transform works correctly in xml spy 5.0, but put some garbage data up front when running the transform via c# code.  Here is the xml doc...
<CustModRq>
      <RqUID>BE59411C-8AD2-4F0D-9285-D417C28CF8A3</RqUID>
      <Customer>
            <CustId>
                  <SPName>SomeSP</SPName>
                  <CustPermId>0000002663</CustPermId>
            </CustId>
            <FIInfo>
                  <BankId>001</BankId>
            </FIInfo>
            <CustProf>
                  <ParsedFlag>1</ParsedFlag>
                  <PersonName/>
                  <CustAddr>
                        <AddrCode>PRIMARY</AddrCode>
                  </CustAddr>
                  <Credit/>
                  <Employment>
                        <EmpAddr>
                              <AddrCode>EMPLOYMENT</AddrCode>
                        </EmpAddr>
                        <EmpStartDt updateflag="1">
                              <Year>1995</Year>
                              <Month>1</Month>
                              <Day>1</Day>
                        </EmpStartDt>
                  </Employment>
                  <CustType updateflag="1">Personal</CustType>
            </CustProf>
            <ShortName updateflag="1">BINCH MADONNA </ShortName>
            <UploadStatusCode>UploadPending</UploadStatusCode>
      </Customer>
</CustModRq>

Here is the xslt:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:space="preserve">
      <xsl:output method="xml"/>
      <xsl:template match="/">
            <xsl:apply-templates/>
      </xsl:template>
      <xsl:template match="CustModRq">
            <xsl:copy>
                  <xsl:apply-templates select="*|comment()|text()"/>
            </xsl:copy>
      </xsl:template>
      <xsl:template match="CustModRq//*">
            <xsl:variable name="par2" select="parent::*"/>
            <xsl:if test="name()='CustIdType' and name($par2)='CustProf'">
                  <xsl:if test="(count(//CustIdType) = 1) and (./SeqId = 2)">
                        <CustIdType>
                              <SeqId>1</SeqId>
                        </CustIdType>
                  </xsl:if>
            </xsl:if>
            <xsl:copy>
                  <xsl:apply-templates select="*|comment()|text()"/>
            </xsl:copy>
            <xsl:if test="name()='RqUID'">
                  <CustModFlag>
                        <xsl:for-each select="/">
                              <xsl:for-each select="//*">
                                    <xsl:for-each select="*[@updateflag]">
                                          <xsl:variable name="par" select="parent::*"/>
                                          <xsl:choose>
                                                <xsl:when test="(name()='Addr1' or name()='HouseNum' or name()='HouseName' or name() = 'Country' or name()='Quadrant' or name()=
'FullName' or name()='Street' or name()='StreetType' or name()='ApartmentNum' or name()='District' or name()='County' or name()='CountryCode' or name()='City' or name()='StateProv' or name()='Addr2' or name()='Addr3' or name()='Addr4' or name()='Addr5' or name()='ZipCode' or name()='PostalCode' or name()='ZipCodeSuffix')">
                                                      <xsl:choose>
                                                            <xsl:when test="parent::node()/AddrCode = 'PRIMARY' ">
                                                                  <xsl:element name="{concat(name($par),name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="parent::node()/AddrCode = 'ALTERNATE' ">
                                                                  <xsl:element name="{concat('Alt',name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:otherwise>
                                                                  <xsl:element name="{concat(name($par),name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:otherwise>
                                                      </xsl:choose>
                                                </xsl:when>
                                                <xsl:when test="name()='RelationCode' or name()='CustPermId' or name()='FullName'">
                                                      <xsl:element name="{concat(name($par),name(),'ChgFlag')}">1</xsl:element>
                                                </xsl:when>
                                                <xsl:when test="name()='EmpIncomeSource'">
                                                      <xsl:element name="{concat('PrimarySourceOfIncome','ChgFlag')
}">1</xsl:element>
                                                </xsl:when>
                                                <!-- FAN - ID#8075 - handle cif amount fields from financial data section-->
                                                <xsl:when test="name()='Amt'">
                                                      <xsl:choose>
                                                            <xsl:when test="name($par)='EmpIncomeAmt'">
                                                                  <xsl:element name="{concat('EmpIncomeAmt','ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="name($par)='LiqAssetsAmt'">
                                                                  <xsl:element name="{concat('LiqAssetsAmt','ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="name($par)='CashAmt'">
                                                                  <xsl:element name="{concat('CashAmt','ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:otherwise>
                                                                  <xsl:element name="{concat(name($par),'ChgFlag')}">1</xsl:element>
                                                            </xsl:otherwise>
                                                      </xsl:choose>
                                                </xsl:when>
                                                <xsl:when test="name()='PhoneNum'">
                                                      <xsl:choose>
                                                            <xsl:when test="PhoneType = 'CellPhone'">
                                                                  <xsl:element name="CellPhoneChgFlag">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="PhoneType = 'EvePhone'">
                                                                  <xsl:element name="EvePhoneChgFlag">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="PhoneType = 'DayPhone'">
                                                                  <xsl:element name="DayPhoneChgFlag">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="PhoneType = 'DayFax'">
                                                                  <xsl:element name="DayFaxChgFlag">1</xsl:element>
                                                            </xsl:when>
                                                      </xsl:choose>
                                                </xsl:when>
                                                <xsl:when test="(name()='AcctId') and name($par)='CardAcctId' ">
                                                      <xsl:choose>
                                                            <xsl:when test="parent::node()/AcctType = 'DC' ">
                                                                  <xsl:element name="{concat('DCCardAcctId', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="parent::node()/AcctType = 'MC' ">
                                                                  <xsl:element name="{concat('MCCardAcctId', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="parent::node()/AcctType = 'VS' ">
                                                                  <xsl:element name="{concat('VISACardAcctId', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="parent::node()/AcctType = 'AT' ">
                                                                  <xsl:element name="{concat('ATMCardAcctId', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                      </xsl:choose>
                                                </xsl:when>
                                                <xsl:when test="(name()='CardHolderFlag') and name($par)='CardAcctId' ">
                                                      <xsl:choose>
                                                            <xsl:when test="parent::node()/AcctType = 'DC' ">
                                                                  <xsl:element name="{concat('DCCCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="parent::node()/AcctType = 'MC' ">
                                                                  <xsl:element name="{concat('MCCCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                                  <xsl:element name="{concat('MCCCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="parent::node()/AcctType = 'VS' ">
                                                                  <xsl:element name="{concat('VISACCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="parent::node()/AcctType = 'AT' ">
                                                                  <xsl:element name="{concat('ATMCCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                      </xsl:choose>
                                                </xsl:when>
                                                <xsl:when test="(name()='ExpDt') and name($par)='CCMotoAcct' ">
                                                      <xsl:choose>
                                                            <xsl:when test="ancestor::node()/AcctType = 'DC' ">
                                                                  <xsl:element name="{concat('DCCCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="ancestor::node()/AcctType = 'MC' ">
                                                                  <xsl:element name="{concat('MCCCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="ancestor::node()/AcctType = 'VS' ">
                                                                  <xsl:element name="{concat('VISACCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                            <xsl:when test="ancestor::node()/AcctType = 'AT' ">
                                                                  <xsl:element name="{concat('ATMCCMotoAcct', name(),'ChgFlag')}">1</xsl:element>
                                                            </xsl:when>
                                                      </xsl:choose>
                                                </xsl:when>
                                                <xsl:when test="name($par)='CustIdType' and name() != 'SeqId'">
                                                      <xsl:variable name="pos" select="preceding-sibling::SeqId/."/>
                                                      <xsl:element name="{concat(name(), $pos, 'ChgFlag')}">1</xsl:element>
                                                </xsl:when>
                                                <xsl:when test="(name() = 'Year')  and not(ancestor::CustIdType)">
                                                      <xsl:element name="{concat(name($par),'ChgFlag')}">1</xsl:element>
                                                </xsl:when>
                                                <xsl:otherwise>
                                                      <xsl:element name="{concat(name(),'ChgFlag')}">1</xsl:element>
                                                </xsl:otherwise>
                                          </xsl:choose>
                                    </xsl:for-each>
                              </xsl:for-each>
                        </xsl:for-each>
                  </CustModFlag>
            </xsl:if>
      </xsl:template>
</xsl:stylesheet>

In spy, the output is....
<?xml version="1.0" encoding="UTF-8"?><CustModRq><RqUID>BE59411C-8AD2-4F0D-9285-D417C28CF8A3</RqUID><CustModFlag><ShortNameChgFlag>1</ShortNameChgFlag><CustTypeChgFlag>1</CustTypeChgFlag><EmpStartDtChgFlag>1</EmpStartDtChgFlag></CustModFlag><Customer><CustId><SPName>SomeSP</SPName><CustPermId>0000002663</CustPermId></CustId><FIInfo><BankId>001</BankId></FIInfo><CustProf><ParsedFlag>1</ParsedFlag><PersonName/><CustAddr><AddrCode>PRIMARY</AddrCode></CustAddr><Credit/><Employment><EmpAddr><AddrCode>EMPLOYMENT</AddrCode></EmpAddr><EmpStartDt><Year>1995</Year><Month>1</Month><Day>1</Day></EmpStartDt></Employment><CustType>Personal</CustType></CustProf><ShortName>BINCH MADONNA </ShortName><UploadStatusCode>UploadPending</UploadStatusCode></Customer></CustModRq>

And here is the code snippet I am using....

XmlDocument xslDoc = new XmlDocument();
                        xslDoc.PreserveWhitespace = false;
                        xslDoc.LoadXml(xslt);
                        StringWriter swTransform = new StringWriter();
                        XslTransform myXslTransform = new XslTransform();
                        
                        myXslTransform.Load((System.Xml.XPath.IXPathNavigable)xslDoc, null, null);
                        myXslTransform.Transform(doc, null, swTransform, null);
                        myXslTransform = null;
                        swTransform.Flush();
                        swTransform.Close();
                        return swTransform.ToString();

... that returns the following as swTransform.ToString() :

<?xml version="1.0" encoding="utf-16"?>CSRFiservCBSleeceNONEfiserv0FiservCbsDesktop.Sales0.1FISERVAE7700FEFDA2467BA19A647C3845C0CD97-96ED-40C7-9F88-897ED1AB16940E91CC1B1C26A5A89B97155D4B7743DC172.254.5.122FISERV1tammi40665009-1752-40C8-8241-25EE920D5421FiservCBS<CustModRq><RqUID>78DB37C2-F275-492D-B089-83ADD9EC04EB</RqUID><CustModFlag><ShortNameChgFlag>1</ShortNameChgFlag><CustTypeChgFlag>1</CustTypeChgFlag><EmpStartDtChgFlag>1</EmpStartDtChgFlag></CustModFlag><Customer><CustId><SPName>SomeSP</SPName><CustPermId>0000002663</CustPermId></CustId><FIInfo><BankId>001</BankId></FIInfo><CustProf><ParsedFlag>1</ParsedFlag><PersonName></PersonName><CustAddr><AddrCode>PRIMARY</AddrCode></CustAddr><Credit></Credit><Employment><EmpAddr><AddrCode>EMPLOYMENT</AddrCode></EmpAddr><EmpStartDt><Year>1995</Year><Month>1</Month><Day>1</Day></EmpStartDt></Employment><CustType>Personal</CustType></CustProf><ShortName>BINCH MADONNA </ShortName><UploadStatusCode>UploadPending</UploadStatusCode></Customer></CustModRq>


I see that the UTF-encoding is different, but not sure that explains this....
Also, the 'stuff' that it is putting in is indeed in the parent nodes of the document, but via debug I can see that it is not what is being passed to the code - only the xmldoc I pasted here.

Any help is appreciated, as always....

Faith
0
faithern
Asked:
faithern
  • 3
1 Solution
 
b1xml2Commented:
i get this:
  <?xml version="1.0" encoding="utf-8" ?>
- <CustModRq>
  <RqUID>BE59411C-8AD2-4F0D-9285-D417C28CF8A3</RqUID>
- <CustModFlag>
  <ShortNameChgFlag>1</ShortNameChgFlag>
  <CustTypeChgFlag>1</CustTypeChgFlag>
  <EmpStartDtChgFlag>1</EmpStartDtChgFlag>
  </CustModFlag>
- <Customer>
- <CustId>
  <SPName>SomeSP</SPName>
  <CustPermId>0000002663</CustPermId>
  </CustId>
- <FIInfo>
  <BankId>001</BankId>
  </FIInfo>
- <CustProf>
  <ParsedFlag>1</ParsedFlag>
  <PersonName />
- <CustAddr>
  <AddrCode>PRIMARY</AddrCode>
  </CustAddr>
  <Credit />
- <Employment>
- <EmpAddr>
  <AddrCode>EMPLOYMENT</AddrCode>
  </EmpAddr>
- <EmpStartDt>
  <Year>1995</Year>
  <Month>1</Month>
  <Day>1</Day>
  </EmpStartDt>
  </Employment>
  <CustType>Personal</CustType>
  </CustProf>
  <ShortName>BINCH MADONNA</ShortName>
  <UploadStatusCode>UploadPending</UploadStatusCode>
  </Customer>
  </CustModRq>
0
 
b1xml2Commented:
code
===
XPathDocument document = new XPathDocument(@"c:\data.xml");
XslTransform stylesheet = new XslTransform();
MemoryStream stream = new MemoryStream();
stylesheet.Load(@"c:\data.xslt");
XmlTextWriter writer = new XmlTextWriter(stream,System.Text.Encoding.UTF8);
writer.WriteProcessingInstruction("xml","version='1.0' encoding='UTF-8'");
stylesheet.Transform(document.CreateNavigator(),null,writer,null);
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
string value = reader.ReadToEnd();
reader.Close();
writer.Close();

xslt
===
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xsl:space="preserve">
<xsl:output method="xml" version="1,0" encoding="utf-8"/>
...

</xsl:stylesheet>
0
 
faithernAuthor Commented:
Well, the code you wrote and change to xslt does work, but my inputs are an xmldocument as an XmlNode and the xslt as a string, and rather than re-write the entire code, I would like to know what exactly in the code is causing this to fail.  
If I change the xslt and use my existing code it still gives me the garbage data.  It is only when I use the XPathDocument that it works, but WHY?  And even if I wanted to, how do I take my XMLNode and put it into XPathDocument format?


Thanks
0
 
b1xml2Commented:
1. Always provide the encoding value(in the Xml and Xslt document). With Microsoft's platform, if you do not provide an encoding, the output encoding would invariably be UTF-16 and then because of the way the transformation occurs internally. This applies equally to MSXML3 and 4.
2. Even by using your C# code, I could not get your purported output. I still got the output as posted by me with the exception that the encoding was UTF-16.
3. With the XmlDocument object, you just create the navigator

XmlDocument document = new XmlDocument();
document.Load(..);
.....
stylesheet.Transform(document.CreateNavigator(),null,writer,null);

4.
XmlDocument document = new XmlDocument();
....
XmlDocument stylesheetDocument = new XmlDocument();
stylesheetDocument.LoadXml(...);
XslTransform stylesheet = new XslTransform();
stylesheet.Load(stylesheetDocument.CreateNavigator(),null,null);
MemoryStream stream = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(stream,System.Text.Encoding.UTF8);
writer.WriteProcessingInstruction("xml","version='1.0' encoding='UTF-8'");
stylesheet.Transform(document.CreateNavigator(),null,writer,null);
stream.Position = 0;
StreamReader reader = new StreamReader(stream);
string value = reader.ReadToEnd();
reader.Close();
writer.Close();
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now