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)
&lt;     <     小餘
&gt;     >     大餘
&amp;    &     和號
&apos;   '     單引號
&quot;   "     雙引號

而由於我直接整個文件中所有&做取代會導致
在原本xml就是用特殊標記的&lt  ---> 前面的也會被取代掉


而實際上&Lstrok;
也是拉丁語系當中某個特殊字符(但是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)

留言

這個網誌中的熱門文章

何謂淨重(Net Weight)、皮重(Tare Weight)與毛重(Gross Weight)

Architecture(架構) 和 Framework(框架) 有何不同?_軟體設計前的事前規劃的藍圖概念

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header