为 XDocument 指定默认命名空间给出空值
Specifiying a default namespace for XDocument gives empty value
当我尝试从文本中解析 XDocument 时,我可以获得这样的默认命名空间:
var xmlDocument1 = XDocument.Parse("<root xmlns='http://somenamespace'></root>");
var xmlNamespace1 = xmlDocument1.Root.GetDefaultNamespace().NamespaceName; // somenamespace
但是,如果我尝试手动创建 XDocument,我会得到一个空值:
var xmlRoot2 = new XElement(XName.Get("root", "http://somenamespace"));
var xmlDocument2 = new XDocument(xmlRoot2);
var xmlNamespace2 = xmlDocument2.Root.GetDefaultNamespace().NamespaceName; // is empty
我希望 xmlNamespace2 为“http://somenamespace”。我做错了什么吗?
编辑: 建议重复中的答案无法解决我的问题,即使我使用此处建议的功能也是如此:
How to set the default XML namespace for an XDocument
我仍然会得到空的命名空间。这是链接问题的解决方案:
class Program
{
static void Main(string[] args)
{
var xmlRoot = new XElement(XName.Get("root"));
var xmlDocument = new XDocument(xmlRoot);
SetDefaultXmlNamespace(xmlRoot, "http://somenamespace");
var xmlNamespace = xmlDocument.Root.GetDefaultNamespace().NamespaceName; // is empty
}
public static void SetDefaultXmlNamespace(XElement xelem, XNamespace xmlns)
{
if (xelem.Name.NamespaceName == string.Empty)
xelem.Name = xmlns + xelem.Name.LocalName;
foreach (var e in xelem.Elements())
SetDefaultXmlNamespace(e, xmlns);
}
}
默认命名空间仍然是空的。
是的,这很棘手,因为即使字符串表示形式看起来不错,它仍然不起作用。
对于教育,添加:
var xml3 = xmlDocument2.ToString();
var xmlDocument3 = XDocument.Parse(xml3);
var xmlNamespace3 = xmlDocument3.Root.GetDefaultNamespace().NamespaceName;
所以只有在您再次解析 xml 文本后,它才是您所期望的。
可能最短的方法:
var xmlRoot2 = new XElement(XName.Get("root", "http://somenamespace"),
new XAttribute("xmlns", "http://somenamespace"));
使用预定义的 XNameSpace.Xmlns
不适用于默认(无前缀)命名空间,因此只需 "xmlns"
即可。
我想我明白为什么我没有获得默认命名空间。根据MSDN:
When creating XML trees using C#, even if an XML tree would be
serialized with a default namespace, if the namespace is not persisted
in the XML tree as an attribute, this method will not report the
namespace as the default namespace.
所以我可能需要显式设置 xmlns 属性:
class Program
{
static void Main(string[] args)
{
var xmlRoot = new XElement(XName.Get("root", "http://somenamespace"));
xmlRoot.SetAttributeValue("xmlns", "http://somenamespace");
var xmlDocument = new XDocument(xmlRoot);
var xmlNamespace = xmlDocument.Root.GetDefaultNamespace().NamespaceName;
}
}
现在我得到了正确的命名空间名称。
当我尝试从文本中解析 XDocument 时,我可以获得这样的默认命名空间:
var xmlDocument1 = XDocument.Parse("<root xmlns='http://somenamespace'></root>");
var xmlNamespace1 = xmlDocument1.Root.GetDefaultNamespace().NamespaceName; // somenamespace
但是,如果我尝试手动创建 XDocument,我会得到一个空值:
var xmlRoot2 = new XElement(XName.Get("root", "http://somenamespace"));
var xmlDocument2 = new XDocument(xmlRoot2);
var xmlNamespace2 = xmlDocument2.Root.GetDefaultNamespace().NamespaceName; // is empty
我希望 xmlNamespace2 为“http://somenamespace”。我做错了什么吗?
编辑: 建议重复中的答案无法解决我的问题,即使我使用此处建议的功能也是如此: How to set the default XML namespace for an XDocument 我仍然会得到空的命名空间。这是链接问题的解决方案:
class Program
{
static void Main(string[] args)
{
var xmlRoot = new XElement(XName.Get("root"));
var xmlDocument = new XDocument(xmlRoot);
SetDefaultXmlNamespace(xmlRoot, "http://somenamespace");
var xmlNamespace = xmlDocument.Root.GetDefaultNamespace().NamespaceName; // is empty
}
public static void SetDefaultXmlNamespace(XElement xelem, XNamespace xmlns)
{
if (xelem.Name.NamespaceName == string.Empty)
xelem.Name = xmlns + xelem.Name.LocalName;
foreach (var e in xelem.Elements())
SetDefaultXmlNamespace(e, xmlns);
}
}
默认命名空间仍然是空的。
是的,这很棘手,因为即使字符串表示形式看起来不错,它仍然不起作用。
对于教育,添加:
var xml3 = xmlDocument2.ToString();
var xmlDocument3 = XDocument.Parse(xml3);
var xmlNamespace3 = xmlDocument3.Root.GetDefaultNamespace().NamespaceName;
所以只有在您再次解析 xml 文本后,它才是您所期望的。
可能最短的方法:
var xmlRoot2 = new XElement(XName.Get("root", "http://somenamespace"),
new XAttribute("xmlns", "http://somenamespace"));
使用预定义的 XNameSpace.Xmlns
不适用于默认(无前缀)命名空间,因此只需 "xmlns"
即可。
我想我明白为什么我没有获得默认命名空间。根据MSDN:
When creating XML trees using C#, even if an XML tree would be serialized with a default namespace, if the namespace is not persisted in the XML tree as an attribute, this method will not report the namespace as the default namespace.
所以我可能需要显式设置 xmlns 属性:
class Program
{
static void Main(string[] args)
{
var xmlRoot = new XElement(XName.Get("root", "http://somenamespace"));
xmlRoot.SetAttributeValue("xmlns", "http://somenamespace");
var xmlDocument = new XDocument(xmlRoot);
var xmlNamespace = xmlDocument.Root.GetDefaultNamespace().NamespaceName;
}
}
现在我得到了正确的命名空间名称。