0

I have an XMLDocument which i am deserializing into object in my C# code. It works fine until i have nodes like below,

  <Name>ABC</Name>
  <Message>Invalid Name</Message>

In the above scenario what i get inside my C# object would be Name = ABC and Message = Invalid Name.

But now i have a requirement to read a complete XML node inside XMLDocument. Which is like this,

<ReadXML><fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
          <entity name="customerproduct">
            <attribute name="customerproductid" />
            <attribute name="name" />
            <attribute name="createdon" />
            <attribute name="customertype" />
            <attribute name="custodian_customerproductid" />
            <attribute name="accountnumber" />
            <order attribute="name" descending="false" />
            <filter type="and">
              <condition attribute="productgroup" operator="eq" uiname="Credit Cards" uitype="productgroup" value="{12344}" />
              <condition attribute="customer" operator="eq" uiname="abc xyz" uitype="contact" value="{1234}" />
            </filter>
          </entity>
        </fetch></ReadXML>

I have an object ReadXML inside my C# code and i was looking to get complete XML that is inside ReadXML node as an string inside my ReadXML variable.

something like this,

string ReadXML = "<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
          <entity name="customerproduct">
            <attribute name="customerproductid" />
            <attribute name="name" />
            <attribute name="createdon" />
            <attribute name="customertype" />
            <attribute name="custodian_customerproductid" />
            <attribute name="accountnumber" />
            <order attribute="name" descending="false" />
            <filter type="and">
              <condition attribute="productgroup" operator="eq" uiname="Credit Cards" uitype="productgroup" value="{12344}" />
              <condition attribute="customer" operator="eq" uiname="abc xyz" uitype="contact" value="{1234}" />
            </filter>
          </entity>
        </fetch>"

Inside my Code i am doing this,

 XmlDocument doc = new XmlDocument();

        doc.Load(@"D:\Development\Framework\TestApplication\XMLScript\XMLScript\XMLFile.xml");


        string XML = doc.InnerXml;
        operationTitle.Text = "Stop Lost Card"; ;
        System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(MyOperation));
        MemoryStream memStream = new MemoryStream(Encoding.UTF8.GetBytes(vrp_XML));
        MyOperation = (MyOperation)serializer.Deserialize(memStream);

And Inside MyOperation Class, i have ReadXML like this,

[XmlElement(ElementName = "ReadXML")]
public string ReadXML { get; set; }

Whenever i try to read the XML into the string i get the following error,

    System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=There is an error in XML document (1, 1329).
  Source=System.Xml
  StackTrace:
       at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
       at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
       at VeriTouch.CRM.USD.AgentScripting.AgentScriptingControl.loadData() in C:\Projects\AgentScripting_30102018\AgentScripting\AgentScripting\AgentScriptingControl.xaml.cs:line 323
       at VeriTouch.CRM.USD.AgentScripting.AgentScriptingControl.StartButton_Click(Object sender, RoutedEventArgs e) in C:\Projects\AgentScripting_30102018\AgentScripting\AgentScripting\AgentScriptingControl.xaml.cs:line 304
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
       at System.Windows.Controls.Primitives.ButtonBase.OnClick()
       at System.Windows.Controls.Button.OnClick()
       at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
       at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
       at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
       at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
       at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
       at System.Windows.Input.InputManager.ProcessStagingArea()
       at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
       at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
       at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
       at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at AgentScripting.App.Main()
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
       HResult=-2146232000
       LineNumber=1
       LinePosition=1329
       Message=Unexpected node type Element. ReadElementString method can only be called on elements with simple or empty content. Line 1, position 1329.
       Source=System.Xml
       StackTrace:
            at System.Xml.XmlReader.ReadElementString()
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUSDOperation.Read4_AgentScript(Boolean isNullable, Boolean checkType)
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUSDOperation.Read5_AgentScripts(Boolean isNullable, Boolean checkType)
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUSDOperation.Read6_AgentBeginScriptList(Boolean isNullable, Boolean checkType)
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUSDOperation.Read11_USDStep(Boolean isNullable, Boolean checkType)
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUSDOperation.Read12_USDSteps(Boolean isNullable, Boolean checkType)
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUSDOperation.Read13_USDOperation(Boolean isNullable, Boolean checkType)
            at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderUSDOperation.Read14_USDOperation()
       InnerException: 

-------------------------------EDIT-------------------------------------------

MyOperation.CS class

public class USDOperation
{
    [XmlElement(ElementName = "OperationCode")]
    public string OperationCode { get; set; }

    [XmlElement(ElementName = "OperationName")]
    public string OperationName { get; set; }

    [XmlElement(ElementName = "AuthorizationLevel")]
    public string AuthorizationLevel { get; set; }

    [XmlElement(ElementName = "AgentBeginScriptList")]
    public AgentBeginScriptList AgentBeginScriptList { get; set; }

    [XmlElement(ElementName = "ReadXML")]
    public string ReadXML { get; set; }

    [XmlElement(ElementName = "USDSteps")]
    public USDSteps USDSteps { get; set; }

    [XmlElement(ElementName = "AgentEndScriptList")]
    public AgentEndScriptList AgentEndScriptList { get; set; }
}
Faran Saleem
  • 404
  • 1
  • 7
  • 31
  • And what is on line 1 at position 1329? – ProgrammingLlama Nov 12 '18 at 06:24
  • The ReadXML node. – Faran Saleem Nov 12 '18 at 06:24
  • could u plz show your `MyOperation` class? – er-sho Nov 12 '18 at 06:26
  • Please recheck the question i have edited it and added the MyOperation.CS Class. But i don't think that the issue is with MyOperation.CS class because whenever pass a string from XML it is read by my C# variables correctly but whenever i am trying to pass XML and trying to read it as string it gives me an error "Invalid XML" – Faran Saleem Nov 12 '18 at 06:31
  • yes it gives your error bcoz xml is not suitable for c# classes. – er-sho Nov 12 '18 at 06:34
  • I want to read, ReadXML node as an string inside my C# variable, how will i achieve it? – Faran Saleem Nov 12 '18 at 06:35
  • first le me know that xml you posted it your full xml or part of xml? – er-sho Nov 12 '18 at 06:35
  • Just a part of XML, this part is making issues since it has an XML, all other parts has just string or sentences which are being read just fine. – Faran Saleem Nov 12 '18 at 06:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/183479/discussion-between-faran-saleem-and-ershoaib). – Faran Saleem Nov 12 '18 at 06:37
  • The ReadXML part is part of XMLDocument which has child nodes inside. I just want to read that complete part inside a string variable in my C# code as i have mentioned in my question. – Faran Saleem Nov 12 '18 at 06:43

3 Answers3

1

The problem is that we cannot serialize/deserialize a complex type to string. Instead we can define our own type and implement IXmlSerializable interface to provide our own implementation.

Below I've defined a MyString class to implement the same. In ReadXml method I'm using innerXml. You may use the outerXml as well.

public class MyString : IXmlSerializable
{
    string _xmlString;
    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        reader.MoveToContent();

        Boolean isEmptyElement = reader.IsEmptyElement;
        if (!isEmptyElement)
        {
            _xmlString = reader.ReadInnerXml();
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteString(_xmlString);
    }
}

The property ReadXML will now be of type MyString instead of string.

[XmlElement(ElementName = "ReadXML")]
public MyString ReadXML { get; set; }

Ref: I got the idea from the following Stackoverflow question https://stackoverflow.com/a/22106996/643318

Taleeb
  • 1,888
  • 18
  • 25
  • one more thing. I am trying to convert that into string. But it is not getting converted. Please tell me how can i access the innerXML and then convert that into string and store it inside a variable. – Faran Saleem Nov 12 '18 at 11:19
  • Can you elaborate. What exactly are you trying to convert? – Taleeb Nov 13 '18 at 06:43
0
var xml=File.ReadAllText(@"D:\Development\Framework\TestApplication\XMLScript\XMLScript\XMLFile.xml")
er-sho
  • 9,581
  • 2
  • 13
  • 26
  • 1
    While this code snippet may be the solution, including an explanation really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Kurt Van den Branden Nov 12 '18 at 14:05
-1
var xml=File.ReadAllText(@"D:\XMLFile.xml");

var xml_l=xml.ToLower();

var ind_1=xml_l.IndexOf("&lt;fetch");
var ind_2=xml_l.IndexOf("&lt;/fetch",ind_1);

var xml_fetch=xml.Substring(ind_1, ind_2 - ind_1+8);
er-sho
  • 9,581
  • 2
  • 13
  • 26
  • 1
    This looks fragile. What if, in future, `fetch1` node or or several `fetch` nodes appear? Or `fetch` node is renamed and one forget to amend `ind_1+8`? This introduces extraneous maintenance costs. – stop-cran Nov 12 '18 at 11:05