【问题标题】:Working With Specific XML structure使用特定的 XML 结构
【发布时间】:2015-01-04 13:49:15
【问题描述】:

我正在尝试从 XML 文档中获取一些数据。我无法控制架构。如果由我决定,我会选择另一个模式。我正在使用 C# 的 XPATH 库来获取数据。

XML 文档

<Journals>
    <name>Title of Journal</name>
    <totalvolume>2</totalvolume>
    <JournalList>
        <Volume no="1">
            <Journal>
                <issue>01</issue>
                <Title>Title 1</Title>
                <date>1997-03-10</date>
                <link>www.somelink.com</link>
            </Journal>
            <Journal>
                <issue>02</issue>
                <Title>Title 3</Title>
                <date>1997-03-17</date>
                <link>www.somelink.com</link>
            </Journal>
        </Volume>
        <Volume no="2">
            <Journal>
                <issue>01</issue>
                <Title>Title 1</Title>
                <date>1999-01-01</date>
                <link>www.somelink.com</link>
            </Journal>
            <Journal>
                <issue>01</issue>
                <Title>Title 2</Title>
                <date>1999-01-08</date>
                <link>www.somelink.com</link>
            </Journal>
        </Volume>
    </JournalList>
 </Journals>

我正在尝试获取第 2 卷节点中的所有数据。到目前为止,这是我尝试过的:

C# 代码

protected void loadXML(string url)
{
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(url);

    string strQuery = "Volume[@no='2']";

    XmlElement nodeList = xmlDoc.DocumentElement;
    XmlNodeList JournalList = nodeList.SelectNodes(strQuery);

    foreach (XmlElement Journal in JournalList)
    {
        XmlElement temp = Journal;
    }
}

JournalList 中似乎没有节点。任何人?提前致谢/

【问题讨论】:

  • 请注意,使用XDocument 比使用 XmlDocument 更容易。使用 XmlDocument,您基本上只能使用 XPath 查询,而使用 XDocument,您可以use LINQ
  • @slugster LINQ 很不错,但它并不是天生就更好。 XPath 可以轻松处理这种情况(以及许多更复杂的情况)。

标签: c# xml xpath


【解决方案1】:

您的代码正在直接在“Journals”节点下寻找“Volume”节点

改变这个:

string strQuery = "Volume[@no='2']";

为此,为了在“JournalList”节点下寻找“Volume”节点:

string strQuery = "JournalList/Volume[@no='2']";

另外,您的 XML 中有几个拼写错误:

</Volume no="2">  ->  <Volume no="2">   // no open tag found

</Journal>        ->  </Journals>       // expecting end tag </Journals>

来自您下面的评论:

我将如何访问每个期刊?例如。我想通过每个“期刊”获得期刊的标题?

为此,您可以稍微修改您的代码:

var nodeList = xmlDoc.DocumentElement;
var volume = nodeList.SelectSingleNode(strQuery);
foreach (XmlElement journal in volume.SelectNodes("Journal"))
{
    var title = journal.GetElementsByTagName("Title")[0].InnerText;
}

【讨论】:

  • 感谢您的回复,但我有一个问题。我将如何访问每个期刊?例如。我想对每个“期刊”感到愤怒并在第 2 卷中获得每个期刊的标题?我想使用 foreach 语句,但似乎只有我被抓住了第 2 卷。我将如何获取其中的节点?
  • @Grant 我相信您的第二个代码示例包含错误。你不应该迭代 xmlDoc.SelectNodes("//JournalList/Volume[@no=2]") 而不是 volume.SelectNodes("Journal") 吗?
  • 啊,我明白了。它的实现比它需要的要复杂一些,但它会起作用。 xmlDoc.SelectNodes("//JournalList/Volume[@no = 2]/Journal") 会直接选择想要的节点,节省几行。
【解决方案2】:

你也可以使用Linq to XML:

using System.Xml.Linq;
//...
string path="Path of your xml file"
XDocument doc = XDocument.Load(path);
var volume2= doc.Descendants("Volume").FirstOrDefault(e => e.Attribute("no").Value == "2");

【讨论】:

  • doc.Descendants("Volume").FirstOrDefault(e =&gt; e.Attribute("no").Value == "2") - 77 个字符。 doc.SelectNodes("//Volume[@no=2]") - 34 个字符,更易于阅读。
猜你喜欢
  • 2014-12-31
  • 2019-01-30
  • 2014-12-29
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多