3
<div xmlns="http://www.com">
  <div class="child">
  </div>
</div>

当我使用 xpath 获取子元素并执行.ToString()时,它会将父命名空间添加到它。如何在没有冗余名称空间的情况下获取内容?

4

3 回答 3

3

您可以使用此扩展方法。它将递归地创建另一个 XElement,包括其没有命名空间的子元素。扩展方法需要放在静态类中:

 public static XElement IgnoreNamespace(this XElement xelem)
    {
        XNamespace xmlns = "";
        var name = xmlns + xelem.Name.LocalName;
        return new XElement(name,
                        from e in xelem.Elements()
                        select e.IgnoreNamespace(),
                        xelem.Attributes()
                        );
    }


static void Main(string[] args)
{
    var document = XDocument.Parse("<?xml version=\"1.0\" ?><div xmlns=\"http://www.ya.com\"><div class=\"child\"></div></div>");
    var first = document.Root.Elements().First().IgnoreNamespace();
    Console.WriteLine(first.ToString());
}
于 2012-07-13T07:53:01.737 回答
2

拉曼的答案很好,但它不适用于这样的 XML:

<div xmlns="http://www.ya.com">
   <div class="child">
      **This is some text**
   </div>
</div>

这是我改进的版本,可以工作:

public static XElement IgnoreNamespace(this XElement xelem)
{
    XNamespace xmlns = "";
    var name = xmlns + xelem.Name.LocalName;

    var result = new XElement(name,
                     from e in xelem.Elements()
                     select e.IgnoreNamespace(),
                     xelem.Attributes()
                     );

    if (!xelem.HasElements)
        result.Value = xelem.Value;

    return result;
}
于 2013-10-16T09:04:08.943 回答
0

这里提供的答案都不适合我。对于在这里登陆的其他任何人,使用我自己的大型 xaml 文件和代码片段中包含的示例进行测试。

void Main()
{
    var path = @"C:\Users\User\AppData\Local\Temp\sample.xml";
    var text = File.ReadAllText(path);
    var surrounded = "<test xmlns=\"http://www.ya.com\">" + text + "</test>";
    var xe = XElement.Parse(surrounded);

    xe.Dump();
    xe.StripNamespaces().Dump();

    var sampleText = "<test xmlns=\"http://www.ya.com\"><div class=\"child\" xmlns:diag=\"http://test.com\"> ** this is some text **</div></test>";
    xe = XElement.Parse(sampleText);
    xe.Dump();
    xe.StripNamespaces().Dump();
}

public static class Extensions
{
    public static XNode StripNamespaces(this XNode n)
    {
        var xe = n as XElement;
        if(xe == null)
            return n;
        var contents = 
            // add in all attributes there were on the original
            xe.Attributes()
            // eliminate the default namespace declaration
            .Where(xa => xa.Name.LocalName != "xmlns")
            .Cast<object>()
            // add in all other element children (nodes and elements, not just elements)
            .Concat(xe.Nodes().Select(node => node.StripNamespaces()).Cast<object>()).ToArray();
        var result = new XElement(XNamespace.None + xe.Name.LocalName, contents);
        return result;

    }

#if !LINQPAD
    public static T Dump<T>(this T t, string description = null)
    {
        if(description != null)
            Console.WriteLine(description);
        Console.WriteLine(t);
        return t;
    }
#endif
}

首先写成F#

let stripNamespaces (e:XElement):XElement=
    // if the node is not XElement, pass through
    let rec stripNamespaces (n:XNode): XNode =
        match n with
        | :? XElement as x -> 
            let contents = 
                x.Attributes() 
                // strips default namespace, but not other declared namespaces
                |> Seq.filter(fun xa -> xa.Name.LocalName <> "xmlns")
                |> Seq.cast<obj> 

                |> List.ofSeq 
                |> (@) (
                    x.Nodes() 
                    |> Seq.map stripNamespaces 
                    |> Seq.cast<obj> 
                    |> List.ofSeq
                )
            XElement(XNamespace.None + x.Name.LocalName, contents |> Array.ofList) :> XNode
        | x -> x
    stripNamespaces e :?> XElement
于 2017-01-19T19:06:58.913 回答