Reputation: 3718
I need to use C# to manicure the response from a service before handing it off to the caller. The service takes a series of requests in XML format, formats the message and send it to the service. The response looks similar to this:
<SvcRes>
<SvcVer>1.0</SvcVer>
<MsgUUID>12345678-1234-1234-1234-123456789012</MsgUUID>
<Svc>
<SvcParms>
<ApplID>App</ApplID>
<SvcID>AppSrch</SvcID>
<SvcVer>1.0</SvcVer>
</SvcParms>
<MsgData>
<AppResData>
<Key>xxxxxxxx</Key>
<Rslt>xxxxxxxx</Rslt>
<ErrCde>0</ErrCde>
<ApplMsgLst>
<ApplMsg>
<ApplMsgApplId>D6</ApplMsgApplId>
<ApplMsgNbr>0</ApplMsgNbr>
<ApplMsgTxt>INQUIRY COMPLETE 09:23:53</ApplMsgTxt>
<ApplMsgErrInd>N</ApplMsgErrInd>
</ApplMsg>
</ApplMsgLst>
</AppResData>
</MsgData>
<ErrCde>0</ErrCde>
<ErrMsg/>
</Svc>
<Svc>
<SvcParms>
<ApplID>DP</ApplID>
<SvcID>DPKywrd</SvcID>
<SvcVer>1.0</SvcVer>
<RqstUUID>12345678-1234-1234-1234-123456789012</RqstUUID>
</SvcParms>
<MsgData>
<AppResData>
<Key>xxxxxxxx</Key>
<Rslt>xxxxxxxx</Rslt>
<ErrCde>0</ErrCde>
<ApplMsgLst>
<ApplMsg>
<ApplMsgApplId>D6</ApplMsgApplId>
<ApplMsgNbr>0</ApplMsgNbr>
<ApplMsgTxt>INQUIRY COMPLETE 09:23:53</ApplMsgTxt>
<ApplMsgErrInd>N</ApplMsgErrInd>
</ApplMsg>
</ApplMsgLst>
</AppResData>
</MsgData>
<ErrCde>0</ErrCde>
<ErrMsg/>
<Svc>
<ErrCde>0</ErrCde>
<ErrMsg>Success</ErrMsg>
</SvcRes>
I need to pull out the AppResData nodes, then strip out the ApplMsgLst nodes from each of them before sending the results back to the caller. The resulting XML should be like this:
<AppResData>
<Key>xxxxxxxx</Key>
<Rslt>xxxxxxxx</Rslt>
<ErrCde>0</ErrCde>
</AppResData>
<AppResData>
<Key>xxxxxxxx</Key>
<Rslt>xxxxxxxx</Rslt>
<ErrCde>0</ErrCde>
</AppResData>
I can get a list of XElement nodes using the following 2 lines of code:
var xml = XElement.Parse(xmlResponse);
var msgData = xml.DescendantsAndSelf("MsgData");
Is there another way to do this? There is no file, this is all string data in a SOAP web service.
Upvotes: 0
Views: 73
Reputation: 6322
You can try this with Cinchoo ETL - an open source library to do this transformation easily
StringBuilder xml = new StringBuilder();
using (var r = ChoXmlReader.LoadText("*** YOUR XML CONTENTS ***")
.WithXPath("//AppResData")
.WithField("Key")
.WithField("Rslt")
.WithField("ErrCde")
)
{
using (var w = new ChoXmlWriter(xml)
)
{
w.Write(r);
}
}
Console.WriteLine(xml.ToString());
Output:
<Root>
<AppResData>
<Key>xxxxxxxx</Key>
<Rslt>xxxxxxxx</Rslt>
<ErrCde>0</ErrCde>
</AppResData>
<AppResData>
<Key>xxxxxxxx</Key>
<Rslt>xxxxxxxx</Rslt>
<ErrCde>0</ErrCde>
</AppResData>
</Root>
Upvotes: 0
Reputation: 22157
Here is an XSLT based solution.
Parameters:
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/SvcRes">
<root>
<xsl:for-each select="Svc/MsgData/AppResData">
<xsl:copy>
<xsl:copy-of select="Key"/>
<xsl:copy-of select="Rslt"/>
<xsl:copy-of select="ErrCde"/>
</xsl:copy>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
c#
void Main()
{
const string XSLTFILE = @"e:\Temp\DaveN59.xslt";
string inputXML = @"<SvcRes>
...
</SvcRes>";
try
{
StringReader rdr = new StringReader(inputXML);
XPathDocument XPathDoc = new XPathDocument(rdr);
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(XSLTFILE);
StringWriter sw = new StringWriter();
using (XmlWriter xwo = XmlWriter.Create(sw, xslt.OutputSettings))
{
xslt.Transform(XPathDoc, xwo);
}
Console.WriteLine(sw.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Output XML
<root>
<AppResData>
<Key>xxxxxxxx</Key>
<Rslt>xxxxxxxx</Rslt>
<ErrCde>0</ErrCde>
</AppResData>
<AppResData>
<Key>xxxxxxxx</Key>
<Rslt>xxxxxxxx</Rslt>
<ErrCde>0</ErrCde>
</AppResData>
</root>
Upvotes: 1