gpt4 book ai didi

c# - 查找未声明的命名空间前缀

转载 作者:数据小太阳 更新时间:2023-10-29 02:35:00 26 4
gpt4 key购买 nike

我想在加载时使用 Xml 文件检索每个未声明的命名空间前缀(其中 msCurrentContent 是内存流):

xmlCurrentDoc = new XmlDocument();
xmlCurrentDoc.Load(msCurrentContent);

例如,加载带有以下声明的 Xml 文件时: <Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="mondoc" xls:schemaLocation="mondoc.xsd">

它必须检索未声明的前缀 xls不抛出异常(因为它确实知道)。

执行此操作的最佳方法是什么?

感谢您的帮助!

最佳答案

这真的很 hacky,但你可以子类化 XmlNamespaceManager并在遇到未知前缀时添加假命名空间:

public class MyXmlNamespaceManager : XmlNamespaceManager
{
const string DefaultMissingNamespacePrefix = "http://missing.namespace.prefix.net/2014/";

private string MissingNamespacePrefix { get; set; }
private int NextMissingNamespaceIndex { get; set; }

// The dictionary consists of a collection of namespace names keyed by prefix.
public Dictionary<string, List<string>> MissingNamespaces { get; private set; }

public MyXmlNamespaceManager(XmlNameTable nameTable)
: this(nameTable, null) { }

public MyXmlNamespaceManager(XmlNameTable nameTable, string missingNamespacePrefix)
: base(nameTable)
{
this.MissingNamespacePrefix = (string.IsNullOrEmpty(missingNamespacePrefix) ? DefaultMissingNamespacePrefix : missingNamespacePrefix);
this.MissingNamespaces = new Dictionary<string, List<string>>();
}

void AddMissingNamespace(string prefix)
{
if (string.IsNullOrEmpty(prefix))
return;

string uri;
do
{
int index = NextMissingNamespaceIndex++;
uri = MissingNamespacePrefix + index.ToString();
}
while (LookupPrefix(uri) != null); // Just in case.

Debug.WriteLine(string.Format("Missing namespace \"{0}\" found, added fake namespace \"{1}\"", prefix, uri));
AddNamespace(prefix, uri);
MissingNamespaces.Add(prefix, uri);
}

public override bool HasNamespace(string prefix)
{
var result = base.HasNamespace(prefix);
if (!result)
AddMissingNamespace(prefix);
result = base.HasNamespace(prefix);
return result;
}

public override string LookupNamespace(string prefix)
{
var result = base.LookupNamespace(prefix);
if (result == null)
AddMissingNamespace(prefix);
result = base.LookupNamespace(prefix);
return result;
}
}

public static class DictionaryExtensions
{
public static void Add<TKey, TValue>(this IDictionary<TKey, List<TValue>> listDictionary, TKey key, TValue value)
{
if (listDictionary == null)
throw new ArgumentNullException();
List<TValue> values;
if (!listDictionary.TryGetValue(key, out values))
{
listDictionary[key] = values = new List<TValue>();
}
values.Add(value);
}
}

然后,进行测试:

        string xml = @"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""no""?>
<Document xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""mondoc"" xls:schemaLocation=""mondoc.xsd"">
</Document>
";
XmlDocument xmlDoc;

using (var stream = new StringReader(xml))
{
var settings = new XmlReaderSettings();
settings.NameTable = new NameTable();
var manager = new MyXmlNamespaceManager(settings.NameTable);
XmlParserContext context = new XmlParserContext(null, manager, null, XmlSpace.Default);
using (var xmlReader = XmlReader.Create(stream, settings, context))
{
xmlDoc = new XmlDocument();
xmlDoc.Load(xmlReader);
}
}

string newXml;
using (var writer = new StringWriter())
{
xmlDoc.Save(writer);
newXml = writer.ToString();
}

Debug.WriteLine(newXml);

产生以下结果:

<?xml version="1.0" encoding="utf-16" standalone="no"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="mondoc" xls:schemaLocation="mondoc.xsd" xmlns:xls="http://missing.namespace.prefix.net/2014/0">
</Document>

至少,这不是一个异常(exception)。注意 - 仅部分测试。

关于c# - 查找未声明的命名空间前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27501276/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com