4

我已经加载了一个 XML 文档,现在我希望运行一个 XPath 查询来选择 XML 的某个子集。XML 是

<?xml version="1.0"?>
<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with
      XML.</description>
   </book>
</catalog>

程序类似于

procedure RunXPathQuery(XML: IXMLDOMDocument2; Query: string);
begin

  XML.setProperty('SelectionLanguage', 'XPath');

  NodeListResult := XML.documentElement.selectNodes(Query));

  ShowMessage('Found (' + IntToStr(NodeListResult.length) + ') nodes.');

end;

问题是:当我为上述 XML 运行 XPath 查询“/目录”时,它返回(如预期)1 个元素的节点列表。但是,如果我从查询中删除:xsi<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>重新运行查询,则返回的节点列表为空。如果我删除整个“xmlns”属性,则生成的节点列表再次具有 1 个元素。

所以我的问题是:我能做些什么来解决这个问题,即如何让 MSXML 返回正确数量的实例(在运行 XPath 查询时),而不管命名空间(或其他属性)如何?

谢谢!

4

4 回答 4

3

这个链接

当您使用时<catalog xmlns='http://www.w3.org/2001/XMLSchema-instance'>,整个节点将被移动到不同的(默认)命名空间。您的 XPath 没有在这个其他名称空间内查看,因此它找不到任何数据。<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>您只是将 xsi 声明为不同的名称空间。这将是与默认命名空间不同的命名空间。

我现在无法对其进行测试,但添加类似这样的内容可能会有所帮助:

XML.setProperty('SelectionNamespaces', 'xmlns=''http://www.w3.org/2001/XMLSchema-instance''');

或者也许它没有。正如我所说,我现在无法测试它。

于 2009-10-05T11:14:49.557 回答
2

弄清楚了。似乎我的问题已经在这里这里进行了描述(而且很可能还有无数其他地方)。

查询 /*[local-name()='catalog'] 对我有用。

于 2009-10-05T13:35:16.440 回答
1

利用:

document.setProperty('SelectionNamespaces', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
于 2009-10-05T11:17:10.203 回答
0
/*[local-name()='catalog'] 

是您问题的解决方案。但是你为什么要忽略命名空间呢?它们被引入来表达一些东西,例如区分不同类型的目录。通过您的查询,您现在可以选择世界上任何目录的内容,但我假设您只能处理书籍。如果你得到一个螺丝或汽车的目录,会发生什么?

关于前缀(xsi)的提到的事情是正确的。如果删除前缀,则所有元素都在该命名空间中(然后称为默认命名空间)。但你仍然可以处理它。

在您的代码中,无论如何都要给命名空间一个前缀。它甚至不需要匹配原始前缀:

XML.setProperty('SelectionNamespaces', "xmlns:xyz='http://www.w3.org/2001/XMLSchema-instance'"); 

第二件事是调整 XPath 查询。那么它必须是

/xyz:catalog

原始 XML 仅声明 xsi 命名空间,但从未使用它。在这种情况下,您可以将其完全删除。如果您想使用命名空间并且希望它带有前缀,那么将您的 XML 重写为

<?xml version="1.0"?>
<xsi:catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <xsi:book id="bk101">
    <xsi:author>Gambardella, Matthew</xsi:author>
    <xsi:title>XML Developer's Guide</xsi:title>
    <xsi:genre>Computer</xsi:genre>
    <xsi:price>44.95</xsi:price>
    <xsi:publish_date>2000-10-01</xsi:publish_date>  
    <xsi:description>An in-depth look at creating applications with 
    XML.</xsi:description>
 </xsi:book>
</xsi:catalog>
于 2011-11-17T08:21:42.633 回答