XElement.ToString()包含源中不存在的xmlns

时间:2013-12-11 22:52:36

标签: c# xml

为了解释我的问题,我在运行时使用未知模式的Xml内容。

当我有一个带有默认命名空间的Xml文档时,例如xmlns="someNamespace",每当我在子元素上调用.ToString( )时,xmlns="someNamespace"就出现在文本中,我不能允许在我的情况下。这是一个工作示例来说明:

void Main()
{
    string xml ="<root xmlns=\"someNamespace\"><node>HELLO</node></root>";

    XDocument doc = XDocument.Parse(xml);

    foreach(XNode node in doc.Root.Elements())
    {
        Console.WriteLine(node.ToString());
    }
}

结果是:

<node xmlns="someNamespace">HELLO</node>

请注意source xml中不存在的xmlns。同样,我不知道运行时的模式,因此xmlns和其他属性实际上可能在源中。我根本不想修改。

有什么想法吗?谢谢!

2 个答案:

答案 0 :(得分:1)

因为node元素是root的子元素,所以它继承了root的名称空间声明。要在适当的上下文中解释node,它必须包含父节点的名称空间声明,而不是父节点。否则,名称可能与原始声明中的名称具有不同的含义

答案 1 :(得分:0)

不是答案,而是长篇评论...... JaredPar答案相同且更短。

ToString并且内部/外部XML的所有组合或普通XmlWriter的使用将产生XML等价物(从XML的角度来看)到原始的。在您的情况下,它意味着(正如JaredPar指出的那样)当该节点单独序列化时,默认名称空间声明将向下移动到子节点。

由于您要创建与原始XML不同的XML(由于名称空间不同),您必须手动将节点(可能是所有节点)克隆到默认名称空间中。请注意,您可能会丢失源文本中的属性顺序,并且必须非常小心使用空格。

另一个选择是编写忽略名称空间前缀的自定义XmlWriter或使用XSLT进行复制转换。

注意:前缀(包括空前缀)仅在父节点的上下文中有意义。撕裂子节点而不是携带前缀声明会改变文档的含义。

<r xmlns="urn:u1">
   <c xmlns="urn:u2">
      <d/>
   <c/>
<r/>