2015-05-08 29 views
1

我試圖讀取包含像下面提到的數據元素的XML文檔。如何讀取XML節點的文本元素而不需要剔除使用XmlReader的實體

訪問通過reader.Valuereader.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> 


澄清編輯

問我能確定我的問題,這個問題以後,就是從一個WCF服務調用的上下文中執行從MessageBuffer創建XPathNavigator實例創建一個XmlReader 。因此@ 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

僅供參考,你不應該使用'新的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 
    } 
} 
相關問題