Linq to XML XElement Parse未知命名空间

时间:2012-07-30 06:18:25

标签: c# linq-to-xml

我有一个XML文档。例如:

<Root xmlns:x="anynamespace" xmlns:html="htmlnamespace">
   <x:Data>bla bla</x:Data>
</Root>

这里我有html命名空间来格式化数据。但是元素的值可以是例如
<html:Font ...>bla bla</html:Font>
bla <html:Font ...>bla</htmk:Font>

在我的C#代码中我这样做:
new XElement(main + "Data",myvalue); //main is namespace
结果我得到<x:Data>&lt;html:Font ...&gt;bla bla etc. Linq用他们的文本代码替换了关键标签。所以这是不可接受的。

然后我试了一下:new XElement(main + "Data",XElement.Parse(myvalue));
在那里我得到了前缀html没有被识别的异常。

有人遇到过这样的问题吗?你是怎么解决的?

1 个答案:

答案 0 :(得分:0)

通常你不会从字符串构造内容,而是简单地使用LINQ to XML构造节点,例如。

            XElement foo = XElement.Parse(@"<foo xmlns=""http://example.com/ns1"" xmlns:html=""http://example.com/html"">
  <bar>bar 1</bar>
</foo>");
            foo.Add(new XElement(foo.GetNamespaceOfPrefix("html") + "p", "Test"));

            Console.WriteLine(foo);

创建XML

<foo xmlns="http://example.com/ns1" xmlns:html="http://example.com/html">
  <bar>bar 1</bar>
  <html:p>Test</html:p>
</foo>

如果要解析以字符串形式给出的片段,那么以下方法可能会有所帮助:

        public static void AddWithContext(this XElement element, string fragment)
        {
            XmlNameTable nt = new NameTable();
            XmlNamespaceManager mgr = new XmlNamespaceManager(nt);

            IDictionary<string, string> inScopeNamespaces = element.CreateNavigator().GetNamespacesInScope(XmlNamespaceScope.ExcludeXml);

            foreach (string prefix in inScopeNamespaces.Keys)
            {
                mgr.AddNamespace(prefix, inScopeNamespaces[prefix]);
            }

            using (XmlWriter xw = element.CreateWriter())
            {
                using (StringReader sr = new StringReader(fragment))
                {
                    using (XmlReader xr = XmlReader.Create(sr, new XmlReaderSettings() { ConformanceLevel = ConformanceLevel.Fragment }, new XmlParserContext(nt, mgr, xw.XmlLang, xw.XmlSpace)))
                    {
                        xw.WriteNode(xr, false);
                    }
                }
                xw.Close();
            }
        }
    }

    class Program
    {
        static void Main()
        {
            XElement foo = XElement.Parse(@"<foo xmlns=""http://example.com/ns1"" xmlns:html=""http://example.com/html"">
  <bar>bar 1</bar>
</foo>");
            foo.Add(new XElement(foo.GetNamespaceOfPrefix("html") + "p", "Test"));

            Console.WriteLine(foo);
            Console.WriteLine();

            foo.AddWithContext("<html:p>Test 2.</html:p><bar>bar 2</bar><html:b>Test 3.</html:b>");

            foo.Save(Console.Out, SaveOptions.OmitDuplicateNamespaces);

        }

那样我得到了

<foo xmlns="http://example.com/ns1" xmlns:html="http://example.com/html">
  <bar>bar 1</bar>
  <html:p>Test</html:p>
  <html:p>Test 2.</html:p>
  <bar>bar 2</bar>
  <html:b>Test 3.</html:b>
</foo>