2015-06-22 1 views
1

У меня есть следующий XML:XElement.Value лишает 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> 

и этот код:

[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); 
    } 
} 

serializedContent из xSerializedContent.Value это:

{ 
    "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\"}" 
} 

Как мы видим, <SerializedContent> является JSON и внутри JSON. У меня есть еще один XML внутри EntitiesChanges. Как избежать удалений XML-тегов из<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\"}" 
} 
+4

Используйте CDATA в своем XML? – Bas

+3

На самом деле - помимо всего прочего, это действительно ужасный формат. Неясно, предназначены ли вложенные элементы XML как XML или часть текстовых узлов. Свойство «Значение» делает именно то, для чего оно предназначено, - это конкатенация потоковых текстовых узлов. –

+0

@bas, моя система получает этот xml от третьей стороны и, к сожалению, на данный момент, по крайней мере, я не могу изменить формат. – augustocosta

ответ

2

Как уже отмечалось, этот формат поистине ужасен и будет разорваться, как только XML, встроенный в JSON, будет содержать двойные кавычки (потому что в JSON они будут закодированы как \", что сделает XML недействительным) , JSON действительно должен быть встроен в CDATA.

Теперь, считая, что у вас нет контроля над форматом, вам необходимо прочитать «внутренний XML» элемента <SerializedContent>. Там нет никакой поддержки для этого из коробки, но вы можете легко создать метод расширения, который делает это:

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

Теперь вы можете использовать .GetInnerXml() вместо .Value, и это даст вам ожидаемый результат.

+0

Работал! Большое спасибо. Кроме того, я связался с командой, ответственной за XML, с просьбой заключить SerializedContent в CDATA. – augustocosta

1

Вы используете Value свойство, которое документированное вернуть сцепленные текст потомков узлов внутри элемента.

Итак, похоже, что вы хотите объединить строковые представления всех дочерних узлов. Таким образом, вы можете использовать:

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

Я думаю что должен делать то, что вы хотите, хотя, как отмечалось в комментариях вопрос, это довольно ужасно.

+0

Большое спасибо! Ваше решение сработало. Я выбрал другой ответ только потому, что вывод выглядит лучше без \ r \ n (так что мне не нужно избавляться от этого). Благодаря! – augustocosta