2015-05-08 1 views
1

Я пытаюсь прочитать XML-документ, содержащий элементы, подобные приведенным ниже.Как прочитать текстовый элемент узла XML без разыменования объектов с помощью XmlReader

Доступ к текстовому узлу с помощью reader.Value, reader.ReadContentAsString(), reader.ReadContentAsObject() приводит к считанному значению усекаются до последнего амперсанда, так что в случае данных ниже, что будет ISO^урна: IHE: ITI: XDS: 2013: направление , Используя XmlDocument, текстовые узлы могут быть прочитаны правильно, поэтому я предполагаю, что должен быть способ сделать эту работу также с помощью читателя.

<Slot name="urn:ihe:iti:xds:2013:referenceIdList"> 
       <ValueList> 
       <Value>123456^^^&amp;orgID&amp;ISO^urn:ihe:iti:xds:2013:referral</Value> 
       <Value>098765^^^&amp;orgID&amp;ISO^urn:ihe:iti:xds:2013:referral</Value> 
       </ValueList> 
      </Slot> 


Разъяснение Редактировать

Задав вопрос, я был в состоянии определить мой вопрос пришел от создания XmlReader из XPathNavigator экземпляра, созданного из MessageBuffer, выполняющихся в контексте вызова службы WCF , Таким образом, ответ @ DarkGray был правильным для исходного вопроса, но на самом деле не затрагивал корень проблемы. Я представил второй ответ, который касался моего дела в углу.

System.ServiceModel.Channels.Message message; // the inbound SOAP message 
var buffer = message.CreateBufferedCopy(11 * 1024 * 1024); 
var navigator = buffer.CreateNavigator(); 
var reader = navigator.ReadSubtree(); 
// advance the reader to the text element 
// 
// `reader.Value` now produces ISO^urn:ihe:iti:xds:2013:referral 

ответ

1

Ответ: reader.Value

Выход:

123456^^^&orgID&ISO^urn:ihe:iti:xds:2013:referral 
098765^^^&orgID&ISO^urn:ihe:iti:xds:2013:referral 

Пример:

public static void Execute() 
{ 
    var xml = @" 
    <Slot name='urn:ihe:iti:xds:2013:referenceIdList'> 
     <ValueList> 
     <Value>123456^^^&amp;orgID&amp;ISO^urn:ihe:iti:xds:2013:referral</Value> 
     <Value>098765^^^&amp;orgID&amp;ISO^urn:ihe:iti:xds:2013:referral</Value> 
     </ValueList> 
    </Slot> 
    "; 
    var reader = System.Xml.XmlReader.Create(new System.IO.StringReader(xml)); 
    for (; ;) 
    { 
    if (!reader.Read()) 
     break; 
    if (reader.NodeType == System.Xml.XmlNodeType.Text) 
     Console.WriteLine(reader.Value); 
    } 
} 
+1

FYI, вы не должны использовать 'новый XmlTextReader()' или 'новый XmlTextWriter()'. Они устарели с .NET 2.0. Вместо этого используйте 'XmlReader.Create()' или 'XmlWriter.Create()'. –

+0

К сожалению, это не то поведение, которое я вижу. Точнее, 'reader.value' работает при запуске из linqpad или MSTest, но он обрезается при запуске в контексте вызова службы WCF. – Tedford

+0

@Tedford Возможно, проблема заключается в кодировании или нечитаемых символах в данных? Сделайте простой пример с ошибкой. –

1

Мой вопрос закончилась слишком широким, как некорректное поведение (усечение при использовании reader.Value) только манифест, когда код выполнялся в контексте WCF вызов. Он отлично работал при реализации логики содержащего класса из единичного теста.

Таким образом, выступ установка может быть воспроизведена следующим

неисправного код

System.ServiceModel.Channels.Message message; // the inbound SOAP message 
var buffer = message.CreateBufferedCopy(11 * 1024 * 1024); 
var navigator = buffer.CreateNavigator(); 
var reader = navigator.ReadSubtree(); 
// advance the reader to the text element 
// 
// `reader.Value` now produces ISO^urn:ihe:iti:xds:2013:referral 

После того, как этот экземпляр читателя был создан, то любой XmlText узел чтения из него производится усеченное значение, если они содержатся в тексте ссылку на объект символа. Единственный способ, с помощью которого можно было считывать исходное значение с высокой точностью, заключался в том, чтобы полностью отказаться от использования XPathNavigator и вместо этого воспользоваться хитом создания другого экземпляра Message. Обратите внимание, что исправление использует длинный путь для записи конверта SOAP в поток, поскольку затронутая служба использует кодировку MTOM. Запись в поток непосредственно из MessageBuffer привела к тому, что MIME-заграждения были выписаны.

Исправление

System.ServiceModel.Channels.Message message; // the inbound SOAP 
var buffer = message.CreateBufferedCopy(MaxMessageSize); 
var message = buffer.CreateMessage(); 
using (MemoryStream stream = new MemoryStream()) 
using (XmlWriter writer = XmlWriter.Create(stream)) 
{ 
    message.WriteMessage(writer); 
    writer.Flush(); 
    stream.Position = 0; 

    using (XmlReader reader = XmlReader.Create(stream)) 
    { 
     // business logic goes here 
    } 
} 
Смежные вопросы