XElement.Value is stripping XML tags from content

458 views Asked by At

I have the following XML:

<Message>
    <Identification>c387e36a-0d79-405a-745c-7fc3e1aa8160</Identification>
    <SerializedContent>
        {"Identification":"81d090ca-b913-4f15-854d-059055cc49ff","LogType":0,"LogContent":"{\"EntitiesChanges\":\"
        <audit>
            <username>acfc</username>
            <date>2015-06-04T15:15:34.7979485-03:00</date>
            <entities>
                <entity>
                    <properties>
                        <property>
                            <name>DepId</name>
                            <current>2</current>
                        </property>
                        <property>
                            <name>FirstName</name>
                            <current>camila</current>
                        </property>
                    </properties>
                </entity>
            </entities>
        </audit>\",\"FeatureName\":\"Adicionar Cliente\",\"Operations\":0,\"MachineNameOrigin\":\"VERDE\"}"}
    </SerializedContent>
</Message>

and this code:

[HttpPost]
[ActionName("Message")]
public HttpResponseMessage MessageListener()
{
    var requestString = Request.Content.ReadAsStringAsync().Result;

    try
    {
        var xdoc = XDocument.Parse(requestString);

        var xSerializedContent = xdoc.Root.Element("SerializedContent");    

        var serializedContent = xSerializedContent.Value;

    }
    catch (XmlException e)
    {
        return CreateHttpResponseMessage("Invalid XML. " + e.Message);
    }
    catch (Exception e)
    {
        return CreateHttpResponseMessage(e.Message);
    }
}

The serializedContent from xSerializedContent.Value is this:

{  
    "Identification":"81d090ca-b913-4f15-854d-059055cc49ff",
    "LogType":0,
    "LogContent":"{\"EntitiesChanges\":\"acfc2015-06-04T15:15:34.7979485-03:00DepId2FirstNamecamila\",\"FeatureName\":\"Adicionar Cliente\",\"Operations\":0,\"MachineNameOrigin\":\"VERDE\"}"
}

As we can see the <SerializedContent> is a JSON and inside the JSON I have another XML inside EntitiesChanges. How to avoid the XML tags remotion from the <SerializedContent>?

Expected result:

{  
    "Identification":"81d090ca-b913-4f15-854d-059055cc49ff",
    "LogType":0,
    "LogContent":"{\"EntitiesChanges\":\"<audit><username>acfc</username><date>2015-06-04T15:15:34.7979485-03:00</date><entities><entity><properties><property><name>DepId</name><current>2</current></property><property><name>FirstName</name><current>camila</current></property></properties></entity></entities></audit>\",\"FeatureName\":\"Adicionar Cliente\",\"Operations\":0,\"MachineNameOrigin\":\"VERDE\"}"
}
2

There are 2 answers

1
Thomas Levesque On BEST ANSWER

As others have said, this format is truly horrible, and will break as soon as the XML embedded in the JSON will contain double quotes (because in the JSON they will be encoded as \", which will make the XML invalid). The JSON should really be embedded as CDATA.

Now, assuming that you have no control over the format, you need to read the "inner XML" of the <SerializedContent> element. There is no support for this out of the box, but you can easily create an extension method that does it:

static class XmlExtensions
{
    public static string GetInnerXml(this XNode node)
    {
        using (var reader = node.CreateReader())
        {
            reader.MoveToContent();
            return reader.ReadInnerXml();
        }
    }
}

Now you can use .GetInnerXml() instead of .Value, and it will give you the expected result.

1
Jon Skeet On

You're using the Value property, which is documented to return the concatenated text descendant nodes within the element.

So it sounds like you want a concatenation of the string representations of all the child nodes. So you could use:

var serializedContent = string.Join("", xSerializedContent.Nodes);

I think that should do what you want, although as noted in the question comments, it's pretty horrible.