XElement不应该从其父Xelement继承命名空间吗?

时间:2011-02-11 17:41:37

标签: c# xml linq namespaces

我第一次在.NET 3.5中使用Linq for XML,而我在命名空间方面遇到了一些麻烦。也就是说,XElement打印如下:<opf:metadata>当我只想说<metadata>时。

以下是代码:

    XNamespace opfNamespace = "http://www.idpf.org/2007/opf";
        XNamespace xsi = "http://www.w3.org/2001/XMLSchema-instance";
        XNamespace dcterms = "http://purl.org/dc/terms/";
        XNamespace dc = "http://purl.org/dc/elements/1.1/";

        opfRoot = new XElement(opfNamespace + "package",
                                    new XAttribute("version", "2.0"),
                                    new XAttribute("unique-identifier", "uuid_id"));
        XElement metadata = new XElement(opfNamespace + "metadata",
                                    new XAttribute(XNamespace.Xmlns + "xsi", xsi),
                                    new XAttribute(XNamespace.Xmlns + "opf", opfNamespace),
                                    new XAttribute(XNamespace.Xmlns + "dcterms", dcterms),
                                    new XAttribute(XNamespace.Xmlns + "dc", dc),
                                    new XElement(dc + "language", "pt-BR"));
        opfRoot.Add(metadata);

结果如下:

<?xml version="1.0" encoding="utf-8"?>
<package version="2.0" unique-identifier="uuid_id" xmlns="http://www.idpf.org/2007/opf">
  <opf:metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:opf="http://www.idpf.org/2007/opf" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:language>pt-BR</dc:language>
  </opf:metadata>
</package>

我期望没有opf的元数据元素:“opf:metadata”

如果我从{opfNameSpace +“metadata”}中删除了opfNameSpace,我会在元数据元素中得到一个空白的xmlns命名空间(xmlns =“”)。

我看了这个帖子:

How can I write xml with a namespace and prefix with XElement?

和这一个:

XElement default namespace on attributes provides unexpected behaviour

但他们没有解决我的问题。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

这是因为您在元数据元素中重新声明了opf名称空间别名。只需删除此属性:

new XAttribute(XNamespace.Xmlns + "opf", opfNamespace)
来自<metadata>构造函数调用的

,它运行正常:

<package version="2.0" unique-identifier="uuid_id"
         xmlns="http://www.idpf.org/2007/opf">
  <metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dcterms=
"http://purl.org/dc/terms/" xmlns:dc="http://purl.org/dc/elements/1.1/">
    <dc:language>pt-BR</dc:language>
  </metadata>
</package>

现在您可以争辩说,因为您重新声明了命名空间别名以使其具有与之前相同的URL,所以它应该是无关紧要的 - 说实话,我不知道规范的内容是什么。但这似乎有点合理。

另一方面,我相信这两个XML表单最终会被解析它们的任何东西等同地对待,所以如果使用所有相关声明创建metadata元素更方便,那么它不应该导致任何问题... AFAIK:)

答案 1 :(得分:1)

删除new XAttribute(XNamespace.Xmlns + "opf", opfNamespace),

答案 2 :(得分:0)

由于我需要的命名空间格式非常具体,即使解决了opf:metadata问题也没有正确生成,我找到了更好的方法。我刚刚创建了一个XmlDocument mannualy,并添加了XML。从那里我可以编程编辑它。像这样:

            XmlDocumentopf = new XmlDocument();
            opf.LoadXml("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" +
                            "<package version=\"2.0\" unique-identifier=\"uuid_id\" xmlns=\"http://www.idpf.org/2007/opf\">" +
                            "<metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:opf=\"http://www.idpf.org/2007/opf\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:dcterms=\"http://purl.org/dc/terms/\">" +
                            "<dc:title>Title of this book</dc:title>" +
                            "<dc:language>pt-BR</dc:language>" +
                            "<dc:identifier id=\"uuid_id\" opf:scheme=\"uuid\">a335de4c-560f-4b75-bcba-1418b726f92c</dc:identifier>" +
                            "<dc:creator opf:role=\"aut\">Desconhecido(a)</dc:creator>" +
                            "<dc:date>2011-01-31T11:59:46.949000+00:00</dc:date>" +
                            "<meta name=\"cover\" content=\"book-cover\"/>" +
                            "</metadata>" +
                            "<manifest />" +
                            "<spine toc=\"ncx\" />" +
                            "<guide />" +
                            "</package>");