如何在XML树中加载和添加元素 [英] How to load and add elements in an XML tree

查看:65
本文介绍了如何在XML树中加载和添加元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近几天,我在这里阅读有关Stack Overflow,博客和MSDN文章的内容.我显然对命名空间,Linq和XML如何工作缺乏基本的了解,并且需要帮助.如果我还有更多的头发可以拉出来,那现在就在我的手中:-)

I have spent the last few days reading here on Stack Overflow, blogs, and MSDN articles. I am clearly lacking some basic understanding of how namespaces, Linq, and XML work and am in need of help. If I had more hair to pull out, it would be in my hand right now :-)

使用C#和Linq到XML,我打开以下opf.xml文件:

Using C# and Linq to XML, I open the following opf.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="">
  <metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
  </metadata>
  <manifest></manifest>
  <spine toc="ncx"></spine>
  <guide></guide>
</package>

我用以下代码打开该文件:

I open this file with the following code:

File.Copy(_opfFile, opfFile, true);
XDocument opfDoc = XDocument.Load(opfFile);

不幸的是,这是我完全迷路的地方.我需要做的是在每个主要节点下生成元素.对于metadata节点,我需要创建具有名称空间和非名称空间的元素.对于文件的其余部分,我只需要添加不使用名称空间的常规节点即可.

Here is where I get completely lost, unfortunately. What I need to do is generate elements under each of the major nodes. For the metadata node, I need to create elements with namespaces and non-namespaces. For the remainder of the file, I just need to add regular nodes that do not make use of namespaces.

以下是我要实现的输出的采样.我敢肯定,如果您可以在metdatamanifest节点上提供帮助,我可以弄清楚如何更新其余节点.

Below is a sampling of the output I want to achieve. I am sure if you can help me with the metdata and manifest nodes, I can figure out how to update the rest of the nodes.

<?xml version="1.0" encoding="UTF-8"?>
<package xmlns:ibooks="http://www.idpf.org/2007/opf" unique-identifier="BookId" version="3.0" prefix="ibooks: http://www.idpf.org/2007/opf" 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">
        <dc:title>Untitled</dc:title>
        <meta refines="#contributor" property="role" scheme="marc:relators">bkp</meta>
    </metadata>
    <manifest>
        <item id="toc" href="toc.xhtml" media-type="application/xhtml+xml" properties="nav"/>
    </manifest>
    <spine toc="ncx"></spine>
    <guide></guide>
</package>

能否请您提供一些基本的C#/Linq代码以:

Could you please provide some basic C#/Linq code to:

  1. 如上例所示,查找并添加需要名称空间(ns)为"dc"的metadata个项目.
  2. 添加一个不使用上例中的名称空间的metadata项.
  3. 如上例所示,添加一个新的manifest项.
  1. Find and add metadata items requiring the namesapce (ns) of "dc" as in the example above.
  2. Add a metadata item that does not use a namespace as in the example above.
  3. Add a new manifest item as in the example above.

我会分享我编写的代码,但是到处都是,而且我有很多注释的代码.我可以告诉你的是,我不断地遇到空异常错误.

I would share the code I have written but it is all over the place and I have lots of commented code. What I can tell you is I constantly end up null exception errors.

谢谢.

推荐答案

在对使用多个名称空间的XML进行反向工程时,我发现以下调试实用程序很有用:

When reverse-engineering XML that uses multiple namespaces, I find the following debugging utilities to be useful:

public static class XObjectExtensions
{
    public static IEnumerable<string> DumpXmlAttributeNames(this XObject obj)
    {
        if (obj is XAttribute)
            return new[] { ((XAttribute)obj).Name.ToString() };
        else if (obj is XElement)
        {
            return ((XElement)obj).Attributes().Select(a => a.Name.ToString());
        }
        return Enumerable.Empty<string>();
    }

    public static IEnumerable<string> DumpXmlElementNames(this XElement root)
    {
        if (root == null)
            return Enumerable.Empty<string>();
        return root.DescendantsAndSelf().Select(el => string.Format("{0} \"{1}\"; Attribute names: {2}",
            new string(' ', el.AncestorsAndSelf().Count()), el.Name.ToString(), String.Join(", ", el.DumpXmlAttributeNames().Select(s => "\"" + s + "\""))));
    }

    public static IEnumerable<string> DumpXmlElementNames(this XDocument root)
    {
        if (root == null)
            return Enumerable.Empty<string>();
        return root.Root.DumpXmlElementNames();
    }
}

使用它们,您可以轻松地看到所需XML的元素和属性的正确名称空间:

Using them, one can see easily see the correct namespaces for the elements and attributes for your desired XML:

  "{http://www.idpf.org/2007/opf}package"; Attribute names: "{http://www.w3.org/2000/xmlns/}ibooks", "unique-identifier", "version", "prefix", "xmlns"
   "{http://www.idpf.org/2007/opf}metadata"; Attribute names: "{http://www.w3.org/2000/xmlns/}dc", "{http://www.w3.org/2000/xmlns/}opf"
    "{http://purl.org/dc/elements/1.1/}title"; Attribute names: 
    "{http://www.idpf.org/2007/opf}meta"; Attribute names: "refines", "property", "scheme"
   "{http://www.idpf.org/2007/opf}manifest"; Attribute names: 
    "{http://www.idpf.org/2007/opf}item"; Attribute names: "id", "href", "media-type", "properties"
   "{http://www.idpf.org/2007/opf}spine"; Attribute names: "toc"
   "{http://www.idpf.org/2007/opf}guide"; Attribute names: 

因此,您需要在"http://purl.org/dc/elements/1.1/"命名空间中添加"title"元素,并在"http://www.idpf.org/2007/opf"命名空间中添加其他元素:

Thus you need to add the "title" element in the "http://purl.org/dc/elements/1.1/" namespace and the others in the "http://www.idpf.org/2007/opf" namespace:

        var dc = (XNamespace)"http://purl.org/dc/elements/1.1/";
        var opf = (XNamespace)"http://www.idpf.org/2007/opf";

        var meta = opfDoc.Root.Element(opf + "metadata");
        meta.Add(new XElement(dc + "title", "Untitled"));
        meta.Add(new XElement(opf + "meta", 
            new XAttribute("refines", "#contributor"), 
            new XAttribute("property", "role"), 
            new XAttribute("scheme", "marc:relators"), "bkp"));

        var manifest = opfDoc.Root.Element(opf + "manifest");
        manifest.Add(new XElement(opf + "item", 
            new XAttribute("id", "toc"), 
            new XAttribute("href", "toc.xhtml"), 
            new XAttribute("media-type", "application/xhtml+xml"), 
            new XAttribute("properties", "nav")));

这篇关于如何在XML树中加载和添加元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆