[英]How to fix missing namespace prefix in XML
我有一個XML文件,我自己無法修改。 它包含以下根元素:
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" noNamespaceSchemaLocation="some.xsd">
如您所見, noNamespaceSchemaLocation
缺少前綴xsi:
noNamespaceSchemaLocation
這會導致XmlReader
在驗證時找不到架構信息。 如果添加前綴,一切都很好。 但是正如我所說,我不能修改XML文件(除了測試)。 我從外部來源獲得它們,我的工具應自動驗證它們。
是否可以使XmlReader
解釋沒有xsi:
前綴的noNamespaceSchemaLocation
? 我不想在預處理步驟或類似的步驟中在XML內添加前綴,因為源應該完全保持原樣。
XML錯誤,您需要對其進行修復。 要么讓您的供應商提高其發送質量,要么在到達時對其進行維修。
我不知道您為什么要保留損壞的源(所有質量標准都說這是不好的做法),但是保留損壞的原始版本和修復版本當然是可能的。
XmlReader
的內部結構很丑陋 , 沒有文檔說明 。 因此,此解決方案就像玩火。
我建議的是:一個“添加”缺少的名稱空間的XmlTextReader
。 您可以將此FixingXmlTextReader
直接FixingXmlTextReader
給XDocument.Load()
也可以將其提供給XmlTextReader
/ XmlValidatingReader
(它們都具有接受XmlReader
作為參數的構造函數/ Create
)。
public class FixingXmlTextReader : XmlTextReader
{
public override string NamespaceURI
{
get
{
if (NodeType == XmlNodeType.Attribute && base.LocalName == "noNamespaceSchemaLocation")
{
return NameTable.Add("http://www.w3.org/2001/XMLSchema-instance");
}
return base.NamespaceURI;
}
}
public override string Prefix
{
get
{
if (NodeType == XmlNodeType.Attribute && base.NamespaceURI == string.Empty && base.LocalName == "noNamespaceSchemaLocation")
{
return NameTable.Add("xsi");
}
return base.Prefix;
}
}
public override string Name
{
get
{
if (NodeType == XmlNodeType.Attribute && base.NamespaceURI == string.Empty && base.LocalName == "noNamespaceSchemaLocation")
{
return NameTable.Add(Prefix + ":" + LocalName);
}
return base.Name;
}
}
public override string GetAttribute(string localName, string namespaceURI)
{
if (localName == "noNamespaceSchemaLocation" && namespaceURI == "http://www.w3.org/2001/XMLSchema-instance")
{
namespaceURI = string.Empty;
}
return base.GetAttribute(localName, namespaceURI);
}
public override string GetAttribute(string name)
{
if (name == "xsi:noNamespaceSchemaLocation")
{
name = "noNamespaceSchemaLocation";
}
return base.GetAttribute(name);
}
// There are tons of constructors, take the ones you need
public FixingXmlTextReader(Stream stream) : base(stream)
{
}
public FixingXmlTextReader(TextReader input) : base(input)
{
}
public FixingXmlTextReader(string url) : base(url)
{
}
}
喜歡:
using (var reader = new FixingXmlTextReader("XMLFile1.xml"))
using (var reader2 = XmlReader.Create(reader, new XmlReaderSettings
{
}))
{
// Use the reader2!
}
要么
using (var reader = new FixingXmlTextReader("XMLFile1.xml"))
{
var xdoc = new XmlDocument();
xdoc.Load(reader);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.