2014-11-25 2 views
1

Я десериализую большой XML-документ в объект C#.XML Deserialization of many types

У меня возникла проблема, когда в одной строке есть несколько элементов xml, и у меня возникают проблемы с их правильной перестройкой в ​​коде.

сниппета примера, как так:

<parent> 
    <ce:para view="all"> 
    Text <ce:cross-ref refid="123">[1]</ce:cross-ref> More Text <ce:italic>Italicized text</ce:italic> and more text here 
    </ce:para> 
    <ce:para>...</ce:para> 
</parent> 

Сгенерированный C# класс выглядит следующим образом

[XmlRoot(ElementName = "para", Namespace = "namespace")] 
public class Para 
{ 
    [XmlElement(ElementName = "cross-ref", Namespace = "namespace")] 
    public List<Crossref> Crossref { get; set; } 

    [XmlText] 
    public List<string> Text { get; set; } 

    [XmlElement(ElementName = "italic", Namespace = "namespace")] 
    public List<Italic> Italic { get; set; } 
} 

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

Текста [1] Подробнее Текст Курсив Текст и больше текста здесь

Единственная проблема заключается хотя когда десериализация происходит, порядок теряется каждый бит застрял под соответствующий объект. Это означает, что у меня нет способа узнать, как восстановить строку обратно, как она должна быть.

Text: {"Text", "More Text", "and more text here"} 
Crossref: {"[1]"} 
Italic: {"Italicized Text"} 

Я думал о привлечении всего элемента в виде строки, а затем промывания тегов из него, но я не уверен, как правильно получить его десериализацию. Или, если есть лучший способ сделать это.

Отказ от ответственности: Я не могу изменить XML-документ, поскольку он поступает от третьего лица.

Благодаря

ответ

1

После десериализации 3-й партии XML в объект, который непосредственно соответствует схеме XML, (как вы уже сделали в вашем примере выше), вы должны быть в состоянии использовать XmlNode.InnerText() на <ce:para узел для извлечения что вы ищете без необходимости писать код разбора.

В этот момент вы можете сделать перевод с объекта, который вы десериализовали, из необработанного стороннего XML в объект, который выравнивает узел <ce:para в простую строку.

+0

Спасибо, Крис. В результате я немного изменил ситуацию, используя XDocument и Linq, чтобы получить свой текст, но я хочу отметить ваш ответ так же корректно, как и по вашей логике, чтобы получить результат. – Nick

+0

Если у вас есть время, добавьте свой ответ в качестве альтернативы. Я хотел бы видеть, как вы в конечном итоге его реализовали. –

+1

Я добавил свой ответ, Крис. – Nick

1

Согласно запросу Криса, я отправляю свое решение. Вероятно, он мог бы использовать переработку, поскольку я не очень разбираюсь в запросах linq.

XDocument xdoc = xmlAdapter.GetAsXDoc(xmlstring); 

IEnumerable<XElement> body = from b in xdoc.Descendants() 
            where b.Name.LocalName == "body" 
            select b; 

IEnumerable<XElement> sections = from s in body.Descendants() 
             where s.Name.LocalName == "sections" 
             select s; 

IEnumerable<XElement> paragraphs = from p in sections.Descendants() 
              where p.Name.LocalName == "para" 
              select p; 

string bodytext = ""; 
if (paragraphs.Count() > 0) 
{ 
    StringBuilder text = new StringBuilder(); 
    foreach (XElement p in paragraphs) 
    { 
     text.AppendFormat("{0} ", p.Value); 
    } 
} 

bodytext = text.ToString(); 
+1

Спасибо, что поделился, Ник! p.Value ведет себя очень похоже на node.InnerText() –