【问题标题】:C++ Xerces-c - How to tell if node is placeholderC++ Xerces-c - 如何判断节点是否为占位符
【发布时间】:2012-05-10 13:58:34
【问题描述】:

我一直在使用 C++ 和 Xerces-c 开发 XML 解析器,但我似乎遇到了一个我无法解决的问题(不是主要问题,我可以解决但不要想“破解”我的方式:))

我有一个这样的 XML 文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Config>
<Person>
    <Title>Mr.</Title>
    <Forename>Stephen</Forename>
    <Surname>Cassidy</Surname>
    <Job>
        <Title>Position1</Title>
        <Position>Worker</Position>
        <Salary>£6.40</Salary>
    </Job>
    <Job>
        <Title>NewJob</Title>
        <Position>PositionWorker1</Position>
        <Position>AnotherPosition</Position>
        <Salary>£12,000</Salary>
    </Job>
</Person>

我要做的是弄清楚一个节点是否只是其他子节点的“占位符”,例如像&lt;Person&gt; 节点或&lt;Job&gt; 节点,只检查它的子节点,而不是尝试任何处理。

这样做的原因是我将节点值存储在一个类中,该类存储节点名称(例如 Title)和值(例如 NewJob),以及子条目列表,因此 Job 将是一个节点条目,那么 Title、Position 和 Salary 都将是 Job 的“子”条目。但是,我也希望能够检查 Job 是否已经有 Position 条目,而不是创建一个新条目并将其添加到 Job,只需将 Position 的值添加到已经存在的 Position 条目......如果这样对任何人都有意义:)

任何帮助都将不胜感激,我不希望有人为它编写代码或为我编写任何代码,只是一些提示或指针:)!

【问题讨论】:

  • 为什么将节点存储在自己的类中? Xerces 为此提供了结构。一般来说,我会考虑检查每个子条目的名称,如果它是“位置”,则返回节点。

标签: c++ xml-parsing xerces-c


【解决方案1】:

我建议在这种情况下使用 SAX 解析器。如果您构建自己的对象,则不需要创建 DOM,并且可以在 SAX 运行期间轻松填充自己的对象。这将减少内存消耗,并且在处理大文件时可能会更快。

基本上,使用 SAX 解析器是一个序列

SAX2XMLReaderImpl*  sax_parser = new SAX2XMLReaderImpl();
MyDefaultHandler*  docHandler = new MyDefaultHandler(); // derived from DefaultHandler

sax_parser->setContentHandler(docHandler);
sax_parser->parse(pszPath);

可以在此处找到 SAX 接口的详细文档: SAX2XMLReader

当 Xerces 解析 XML 时,将通过在 MyDefaultHandler 类中实现的回调调用您。根据您的需要在那里填充您的对象。

希望这会有所帮助。

【讨论】:

  • 这可以使用 DOM 解析器来完成。解析器通常会标记遇到的不同类型的节点(例如 text-nodes/plain-char-data-nodes)。
  • 当然他们(DOM 解析器)正在这样做。但是,如果还创建了自己的数据结构,为什么还要创建 DOM 树。在没有更多信息的情况下,我从给定的原始问题中得出了这个事实,因此最好不要也创建 DOM 树。
  • 我对 OP 问题的解读是相反的:我认为他正在使用 DOM 解析器。
  • 是的,我使用的是 DOM 解析器,我无法真正理解 SAX 哈哈,而且文件非常小(不超过几 mb),所以内存不是问题,幸好:)
  • 目前几 MB 并不是很多。希望文件的大小不会随着时间的推移而变大。
【解决方案2】:

Job 应该是 ELEMENT_NODE 类型,而另一个应该是 TEXT_NODE 类型。您可以使用getNodeType() 成员来检查类型,然后根据需要进行操作。

【讨论】:

  • 嗯,我试过了,但由于某种原因, 以 ELEMENT_NODE 的形式出现,然后在它显示为 TEXT_NODE 之后的空格,所以在我的代码中它被作为节点处理包含一个值:S 这不是一个大问题,因为我已经想出了一个解决方法,但是最好能正确地解决它而不是使用黑客:P
  • @SCassidy1986:这是因为解析器保留了空白处理。很可能可以关闭此行为。可以试试DocumentHandler::ignorableWhitespace()吗?
  • 我仍然相信使用 SAX 解析器这个任务会更容易 ;-)
  • @xml-tools.com:SAX 确实有其优势,但有时它可能有点笨拙。
猜你喜欢
  • 1970-01-01
  • 2014-04-26
  • 2014-09-11
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多