Link to home
Start Free TrialLog in
Avatar of _TAD_
_TAD_

asked on

XML and DataSets

I am receiving an xml string into a web service from some 3rd party software.  I need to read that XML, change a value based on other values within the text and then return the xml string.

I can read the data into a data set just fine, but I'm having problems updating the data.  Further, when I send the output the schema looks different.  I can only assume that what I am receiving must be a SOAP string and what I am sending out is not.  However, I don't know much about xml and data sets to really speak intelligently on the subject.


So....  Given that I recieve an xml string, I want to change values stored in the string and then return the "corrected" string, what is the best way to go about this?  DataSet, xmlDocument, ADO recordset??

well written web sites or code snippets are all acceptable answers.
Avatar of _TAD_
_TAD_

ASKER

Here is the XML string that I am receiving (note, that 80% of it is schema, the data is the last line or two)


<xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema"><s:Schema id="RowsetSchema"><s:ElementType name="row" content="eltOnly" rs:updatable="true"><s:AttributeType name="PARAM" rs:number="1" rs:write="true"><s:datatype dt:type="string" dt:maxLength="255" rs:precision="0" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="DATATYPE" rs:number="2" rs:write="true"><s:datatype dt:type="string" dt:maxLength="20" rs:precision="0" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="DIRECTION" rs:number="3" rs:write="true"><s:datatype dt:type="string" dt:maxLength="20" rs:precision="0" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_TEXT" rs:number="4" rs:nullable="true" rs:write="true"><s:datatype dt:type="string" dt:maxLength="1024" rs:precision="0" rs:long="true" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_NUMERIC" rs:number="5" rs:nullable="true" rs:write="true"><s:datatype dt:type="float" dt:maxLength="8" rs:precision="0" rs:fixedlength="true" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_DATETIME" rs:number="6" rs:nullable="true" rs:write="true"><s:datatype dt:type="dateTime" rs:dbtype="timestamp" dt:maxLength="16" rs:scale="0" rs:precision="0" rs:fixedlength="true" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_FILE_NAME" rs:number="7" rs:nullable="true" rs:write="true"><s:datatype dt:type="string" dt:maxLength="255" rs:precision="0" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_FILE_SIZE" rs:number="8" rs:nullable="true" rs:write="true"><s:datatype dt:type="float" dt:maxLength="8" rs:precision="0" rs:fixedlength="true" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_FILE_CONTENTTYPE" rs:number="9" rs:nullable="true" rs:write="true"><s:datatype dt:type="string" dt:maxLength="255" rs:precision="0" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_FILE_DESCRIPTION" rs:number="10" rs:nullable="true" rs:write="true"><s:datatype dt:type="string" dt:maxLength="255" rs:precision="0" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_FILE_ORIGINALPATH" rs:number="11" rs:nullable="true" rs:write="true"><s:datatype dt:type="string" dt:maxLength="255" rs:precision="0" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_FILE_DATELASTMODIFIED" rs:number="12" rs:nullable="true" rs:write="true"><s:datatype dt:type="dateTime" rs:dbtype="timestamp" dt:maxLength="16" rs:scale="0" rs:precision="0" rs:fixedlength="true" rs:maybenull="false"/></s:AttributeType><s:AttributeType name="VALUE_FILE_PATH" rs:number="13" rs:nullable="true" rs:write="true"><s:datatype dt:type="string" dt:maxLength="255" rs:precision="0" rs:maybenull="false"/></s:AttributeType><s:extends type="rs:rowbase"/></s:ElementType></s:Schema><rs:data><rs:insert><z:row PARAM="txtRequesterFName" DATATYPE="TEXT" DIRECTION="INOUT" VALUE_TEXT="John"/><z:row PARAM="txtRequesterLName" DATATYPE="TEXT" DIRECTION="INOUT" VALUE_TEXT="Smith"/></rs:insert></rs:data></xml>



All I want to do is locate the PARAM element that equals "txtRequesterFName" and change the VALUE_TEXT elements's value to something else (e.g. 'Bob' instead of 'John')
ASKER CERTIFIED SOLUTION
Avatar of mandalorian4
mandalorian4

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of _TAD_

ASKER


Thanks Mandalorian4.  I'll take your suggestion into considderation.

quick question though.... How would I get the XML back out?  I assume it would be using the WriteContentTo() funciton.

One of the hurdles I'm running into is that the program that I'm getting this info from is sending it as text, and I need to return the resultant as text.  I'm sure I can pass everything to a memorystream and convert it to ascii from there, but I rather thought that there must be a direct way to output xml as text right from the xml objects (instead of always duming them to a file somewhere, which seems to be the standard).
i've been trying to figure out a solution using xmlDoc.SelectNodes(Xpath,NameSpaceManager);

but i can't seem to figure out the right Xpath to list the nodes, but maybe someone out there could..

i've tried this approach before and it works with a very few lines needed, the problem is that in that code i made, i didnt have namespaces
TAD,

to return your XML document back to text without any pesky IO activity try this:

MemoryStream ms = new MemoryStream()
//After you tweak your doc
xmldoc.Save(ms);

I also looked for a way to go from XMLDocument -> string without saving to a file but could not find a way.

Going from MemoryStream to string shouldn't be too difficult and I did not notice any preformance hit when I developed an application that required XMLDoc -> MemoryStream -> String

Hope that helps
Mandalorian

Avatar of _TAD_

ASKER


mandalorian,
   I got the expected output.  Thanks!


Instead of writing to a memory stream, I just wrote out to a stringbuilder object.
(I only added the last 3 lines the rest is your code)



         XmlDocument xmlDoc = new XmlDocument();
         try
         {
            xmlDoc.LoadXml(xmlText);
            Traverse(xmlDoc.DocumentElement);
         }
         catch(Exception err)
         {
            MessageBox.Show("Blow-up " + err.Message);
         }
       
         StringBuilder xmlOutput = new StringBuilder();
         xmlDoc.WriteContentTo(new XmlTextWriter(new StringWriter((xmlOutput)));

         return xmlOutput.ToString();
Avatar of _TAD_

ASKER



I still feel a bit put out that I can't just drop this in a dataset, make my changes and send the output back to the source.  A dataset would have been a lot easier.... unfortunately the dataset technique seems to change the text of the schema (different standard perhaps??), and that is simply unacceptable for this situation.

Using a xmlDocument is clearly the way I need to go, unfortunately creating it in such a fashion as to be usable for many different applications is going to be difficult or perhaps even impossible given the limitations of the third party tool that I need to use.


any way... thanks for all of your help!
hi, im really intrigued by you problem because my solution (XmlDocument, Dataset and Xpath) can't work with your situation.

is it ok if i ask for the webservice address?
Avatar of _TAD_

ASKER

You won't be able to get to the web service, it's on our internal network.

As for getting your type of solution to work....

I provided the input xml string.   The output needs to look *exactly* like the input.  The only difference is the VALUE_TEXT="John" needs to look like: VALUE_TEXT="Bob".

The reason the xml output needs to look exacty like the input is because the third party tool I'm getting the data from expects the xml file to have the exact schema returned to it.


FYI.... I am using Adobe Acrobat and I am parsing the adobe FDF file (the xml file behind the pdf template that holds all data on the pdf form).
// -- TAD just wanted to share this, i have seeked the help of another expert to solve why i didn't get my solution that i was
// -- supposed to suggest for this problem

---------------------------------------------------------------------
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"C:\wherever\the\file\maybe.xml"); // -- since @ is used, no need for double backslashes (escapes)
XmlNode root = xmlDoc.DocumentElement;

XmlNamespaceManager nsmngr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmngr = GetNamespaces(xmlDoc); // -- a function (definition on the bottom part)

// -- the next line of code searches for a <z:row > nodes with attrbute PARAM = "txtRequesterFName"
// -- irregardless which node level it maybe, the Xpath expression can be modified for any node or attribute you want to find

XmlNodeList nodeList = root.SelectNodes("//z:row[@PARAM=\"txtRequesterFName\"]",nsmngr);

foreach (XmlNode node in nodeList)
{
     node["txtRequesterFName"] = "<New Value you want to assign>";
}

// ... the rest of your code
-----------------------------------------------------------------------

// -- function mentioned above getting the namespaces defined in the XML
public static XmlNamespaceManager GetNamespaces(XmlDocument doc)
{
            XmlNamespaceManager namespaceManager =
                            new XmlNamespaceManager(new NameTable());

            XPathNavigator nav2 = doc.DocumentElement.CreateNavigator();

            if (nav2.MoveToFirstNamespace())
            {
                do
                {
                    if (! nav2.Name.StartsWith("xml"))
                    {
                        namespaceManager.AddNamespace(nav2.Name, nav2.Value);
                    }
                }    while (nav2.MoveToNextNamespace());
            }
            return namespaceManager;
}
// -- code ends

// -- hope that might be of use
thanks to Steve for helping me correct my solution

https://www.experts-exchange.com/M_308259.html