我有一个XML文件,我无法自行修改。它包含以下根元素:
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" noNamespaceSchemaLocation="some.xsd">
正如您所见,xsi:
缺少前缀noNamespaceSchemaLocation
。这会导致XmlReader
在验证时找不到架构信息。如果我添加前缀一切都很好。但正如我所说,我无法修改XML文件(除了测试)。我从外部源获取它们,我的工具应该自动验证它们。
是否有可能在没有XmlReader
前缀的情况下noNamespaceSchemaLocation
解释xsi:
?我不想在预处理步骤或类似的东西中在XML中添加前缀,因为源应该保持原样。
答案 0 :(得分:2)
XML是错误的,您需要修复它。要么让供应商提高他们发送的产品的质量,要么在抵达时进行修理。
我不知道你为什么要保留破碎的来源(所有的质量标准都说这是不好的做法),但它确实可以保留破碎的原件和修复过的原件。版本
答案 1 :(得分:1)
XmlReader
的内部是丑陋 和 无证件。所以这个解决方案就像玩火。
我的建议是:XmlTextReader
“添加”缺少的命名空间。您可以将此FixingXmlTextReader
直接提供给XDocument.Load()
或者您可以将其提供给XmlTextReader
/ XmlValidatingReader
(他们都有一个接受一个的构造函数/ Create
XmlReader
作为参数)
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);
}