C#中XML的Parser處理_load跟loadXML_The entity "xxx" was referenced, but not declared(參考了未宣告的實體xxx)
最近由於在協助院內一項parser 專利XML檔案任務
也因此有機會累積對XML檔案的相關處理經驗
通常在C#進行XML的讀取與Parser
有兩種方法
該方法的overload
Load(Stream)
從指定的資料流載入 XML 文件。
Load(TextReader)
從指定的 TextReader 載入 XML 文件。
Load(String)
從指定的 URL 載入 XML 文件。
Load(XmlReader)
從指定的 XmlReader 載入 XML 文件。
那通常比較容易直接就寫string 傳入xml 檔案路徑
1 2 | XmlDocument XmlDoc = new XmlDocument(); XmlDoc.Load(@"C:\xml_dir\aaa.xml"); |
直到有一天突然跑出詭異的錯誤
參考了未宣告的實體 ’Lstrok’
後來才得知原來
該XML檔案裏頭竟然藏著一個&字符
所以用第二種方式讀取(參考網路其他人解法)
在讀入後先做&的取代
1 2 3 | XmlDocument XmlDoc = new XmlDocument(); string XmlContent = File.ReadAllText(@"C:\xml_dir\aaa.xml"); XmlDoc.LoadXml(XmlContent.Replace("&", "&")); |
然後就又挫屎了~(以後如果看到有人用上面那兩種方式定義,可以先釐清
該XML是如何生成的還有當中內容格式會不會有怪異特殊字符)
因為實際上
有些在XML中有用到如下實體(這是預設XML就會懂得基本entity)
< < 小餘
> > 大餘
& & 和號
' ' 單引號
" " 雙引號
而由於我直接整個文件中所有&做取代會導致
在原本xml就是用特殊標記的< ---> 前面的也會被取代掉
而實際上Ł
也是拉丁語系當中某個特殊字符(但是XML預設不認得的entity)
https://www.toptal.com/designers/htmlarrows/letters/uppercase-l-with-stroke/
https://www.w3.org/TR/WD-math-970515/table18.html
https://www.compart.com/en/unicode/U+0142
那以上方法都不行可能就是類似用白名單來處理
第三種load XML較穩健複雜的寫法(啟用DTD查檢)
1 2 3 4 5 6 7 8 9 10 | XmlDocument XmlDoc = new XmlDocument(); //有拉丁字母HTML Code處理 添加dtd判斷,dtd查檢機制設定開啟 XmlReaderSettings settings = new XmlReaderSettings(); settings.XmlResolver = new XmlUrlResolver(); settings.DtdProcessing = DtdProcessing.Parse; using (StringReader sr = new StringReader(File.ReadAllText(@"C:\xml_dir\aaa.xml"))) using (XmlReader reader = XmlReader.Create(sr, settings)) { XmlDoc.Load(reader); } |
在XML中有所謂dtd(Document Type Definition)的文件的驗證機制
另一種是XML Schema就先不提了
DTD語法:
<!DOCTYPE root-element [element-declarations]>
由於我處理的該份文件有定義此句
要將該檔案創建於讀XML檔的根目錄下相對路徑下
這裡我不曉得為何同事在其他台
安裝的vs2015跑會跳缺少dtd的錯誤而我的vs2019跑不會自動檢測dtd。
照理若你正要讀取進行處裡的XML檔案有定義dtd
若沒有相應在該目錄創建然後直接用load , loadXML會報錯,若你使用時也發現你開發的也是沒有自動查檢dtd的,建議就手動直接將dtd查檢機制開啟。
以上就是XML讀檔案時候經驗分享
之後再遇到就要再去dtd定義額外XML不認得的entity了
Ref:
[C#][Java] 處理讀取 XML 時發生的 The entity "xxx" was referenced, but not declared 例外
[Visual C#]使用XmlDocument讀取發生"System.Xml.XmlException,參考至未宣告的實體nbsp"問題
什麼是 DTD (Document Type Definition)
留言
張貼留言