![](/img/trans.png)
[英]'xi' is an undeclared prefix when setting InnerXml of new XmlDocumentFragment
[英]How to change or inherit the default namespace when setting InnerXml
當設置具有默認命名空間的XmlElement
的InnerXml
時,所有沒有顯式命名空間的標簽都被解析為好像它們具有xmlns=""
,而不是繼承該XmlElement
的默認命名空間(這是在解析真正的 XML 文檔時發生的情況)。
我的問題是:如何將復雜的 XML 字符串解析為文檔片段並將其分配給XmlElement
,並在解析該字符串時繼承目標XmlElement
的命名空間前綴、默認命名空間等?
免責聲明:
XmlElement.InnerXml
關於 XML 命名空間的確切行為是什么。 我不是在問為什么XmlElement.InnerXml
正在做它目前所做的事情,或者這種行為是好是壞。 我問我是否可以改變這種行為或使用其他一些技術來實現我上面描述的。XmlDocument.CreateElement
)保留默認命名空間,但我不想手動實現 XML 解析器並將 XML 字符串轉換為 DOM 操作。可能嗎?
正如Martin Honnen的評論以及Gideon Engelberth的回答中提到的,加載 XDocument 時我可以使用預定義的命名空間嗎? ,您可以在通過XmlReader
解析 XML 時使用XmlParserContext
為命名空間(包括默認命名空間)預定義一個值。 使用配置了適當上下文的XmlReader
,您可以將內部 XML 直接加載到XmlElement
中,並從其范圍繼承任何所需的命名空間。
要僅繼承默認命名空間,請創建以下擴展方法:
public static partial class XmlNodeExtensions
{
public static void SetInnerXmlAndInheritDefaultNamespace(this XmlElement xmlElement, string innerXml)
{
using (var textReader = new StringReader(innerXml))
xmlElement.SetInnerXmlAndInheritDefaultNamespace(textReader);
}
public static void SetInnerXmlAndInheritDefaultNamespace(this XmlElement xmlElement, TextReader innerTextReader)
{
XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable());
mgr.AddNamespace("", xmlElement.GetNamespaceOfPrefix(""));
XmlParserContext ctx = new XmlParserContext(null, mgr, null, XmlSpace.Default);
using (var reader = XmlReader.Create(innerTextReader, new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment, CloseInput = false }, ctx))
using (var writer = xmlElement.CreateNavigator().AppendChild())
{
writer.WriteNode(reader, true);
}
}
}
要繼承所有命名空間(您的問題中的要求並不完全清楚),請創建以下內容:
public static partial class XmlNodeExtensions
{
public static void SetInnerXmlAndInheritNamespaces(this XmlElement xmlElement, string innerXml)
{
using (var textReader = new StringReader(innerXml))
xmlElement.SetInnerXmlAndInheritNamespaces(textReader);
}
public static void SetInnerXmlAndInheritNamespaces(this XmlElement xmlElement, TextReader innerTextReader)
{
XmlNamespaceManager mgr = new XmlNamespaceManager(new NameTable());
var navigator = xmlElement.CreateNavigator();
foreach (var pair in navigator.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml))
mgr.AddNamespace(pair.Key, pair.Value);
XmlParserContext ctx = new XmlParserContext(null, mgr, null, XmlSpace.Default);
using (var writer = navigator.AppendChild())
using (var reader = XmlReader.Create(innerTextReader, new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment, CloseInput = false }, ctx))
{
writer.WriteNode(reader, true);
}
}
}
假設xmlElement
是您想要插入innerXml
字符串的現有XmlElement
,您可以執行以下操作:
xmlElement.SetInnerXmlAndInheritDefaultNamespace(innerXml);
例如,如果您的 XML 文檔看起來像:
<Root xmlns="defaultNameSpace" xmlns:d="dataNodeNamespace"><d:Data></d:Data></Root>
然后將以下 XML 添加到<d:Data>
:
<ElementToAdd Id="10101"><InnerValue>my inner value</InnerValue></ElementToAdd><ElementToAdd Id="20202"><InnerValue>another inner value</InnerValue></ElementToAdd>
結果將是:
<Root xmlns="defaultNameSpace" xmlns:d="dataNodeNamespace">
<d:Data>
<ElementToAdd Id="10101">
<InnerValue>my inner value</InnerValue>
</ElementToAdd>
<ElementToAdd Id="20202">
<InnerValue>another inner value</InnerValue>
</ElementToAdd>
</d:Data>
</Root>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.