现在的位置: 首页 > 综合 > 正文

XmlDocument的selectSingleNode方法,总支持Xpath函数吗?

2012年07月19日 ⁄ 综合 ⁄ 共 4187字 ⁄ 字号 评论关闭

问题
    今天在修改程序的一个BUG时,竟然发现selectSingleNode方法不支持contains Xpath函数,感到很奇怪。在网上和MSDN也没有发现官方言论表明selectSingleNode不支持contains 函数。
当时我的情景大概是这样的:

1、Xml文档的结构

<?xml version="1.0" ?> 
<xsf:xDocumentClass xmlns:xsf="http://schemas.microsoft.com/office/infopath/2003/solutionDefinition">
<xsf:errorCondition expressionContext="T_SUBTITLE/ICHANNELNUM">
  
<xsf:subExpression >Xpath_getSigleNodeValue("T_SUBTITLE/ICHANNELNUM","../ITIMESUSAGE")<1</xsf:subExpression> 
  
</xsf:errorCondition>
<xsf:errorCondition expressionContext="T_DESCAUTHORIZE/ITIMESUSAGE">
  
<xsf:subExpression>Xpath_getSigleNodeValue("T_DESCAUTHORIZE/ITIMESUSAGE","../ICHANNELNUM")<1
</xsf:subExpression> 
  
</xsf:errorCondition>
</xsf:xDocumentClass>

2.我的实现。
   我希望通过代码找到expressionContext不等于T_SUBTITLE/ICHANNELNUM,并且xsf:suExpression中包含字符串"ICHANNELNUM"的节点。我书写了以下代码来实现:

//aObjView_Xsf是存储上述Xml的文档对象
var aObjView_Xsf =new ActiveXObject('MSXML2.DOMDocument');
aObjView_Xsf.load(
"test.xml");
var objerrorConditions = aObjView_Xsf.selectSingleNode("xsf:xDocumentClass/xsf:customValidation/xsf:errorCondition[@expressionContext!='"+strBinding+ "' and contains(xsf:subExpression,'"+fieldName+"')]");

   这时IE报出错误:contains是未实现的方法!。这下我就晕了,明明在Xpath的参考手册,MSDN上都写着contains是支持的方法。

原因

 难道真的不支持?
 查阅MSDN我发现还有以下Xpath函数:

Microsoft XML Core Services (MSXML) 4.0 - XPath Reference

String Functions

concat Returns the concatenation of the arguments.
contains Returns true if the first argument string contains the second argument string; otherwise returns false.
normalize-space Returns the argument string with the white space stripped.
starts-with Returns true if the first argument string starts with the second argument string; otherwise returns false.
string Converts an object to a string.
string-length Returns the number of characters in the string.
substring Returns the substring of the first argument starting at the position specified in the second argument and the length specified in the third argument.
substring-after Returns the substring of the first argument string that follows the first occurrence of the second argument string in the first argument string.
substring-before Returns the substring of the first argument string that precedes the first occurrence of the second argument string in the first argument string.
translate Returns the first argument string with occurrences of characters in the second argument string replaced by the character at the corresponding position in the third argument string.

   难道就只有contains不支持吗?其他函数呢?为了证实我的想法,我尝试了上述所有函数,IE都报出同样的错误,原来都不支持!

原来只有4.0版本的支持
    我发现这些Xpath函数的说明在MSXML 4.0 SDK下,难道只有4.0版本支持?于是我把代码进行了修改:

//aObjView_Xsf是存储上述Xml的文档对象
var aObjView_Xsf =new ActiveXObject('Msxml2.DOMDocument.4.0');
aObjView_Xsf.load(
"test.xml");
var objerrorConditions = aObjView_Xsf.selectSingleNode("xsf:xDocumentClass/xsf:customValidation/xsf:errorCondition[@expressionContext!='"+strBinding+ "' and contains(xsf:subExpression,'"+fieldName+"')]");

     运行程序,竟然不再抛出contains函数不支持的错误了,但是出现另外一个错误,xsf是未定义的前缀。对,应该是没有声明名称空间。我对代码再次进行了修改:

var aObjView_Xsf =new ActiveXObject('Msxml2.DOMDocument.4.0');
aObjView_Xsf.load(
"test.xml");
aObjView_Xsf.setProperty(
"SelectionNamespaces","xmlns:xsf='http://schemas.microsoft.com/office/infopath/2003/solutionDefinition'");
var objerrorConditions = aObjView_Xsf.selectSingleNode("xsf:xDocumentClass/xsf:customValidation/xsf:errorCondition[@expressionContext!='"+strBinding+ "' and contains(xsf:subExpression,'"+fieldName+"')]");

   运行程序,测试通过!于是我下了这样一个结论:只有Msxml2.DOMDocument.4.0以上版本才支持这些Xpath函数。但是这个结论对吗?我自己也不敢确定。

不只Msxml2.DOMDocument 4.0以上版本支持contains等Xpath函数

    我进一步的查找了一些资料,都没有信息表明Msxml2.DOMDocument 2.0不支持这些Xpath函数。到底Msxml2.DOMDocument 2.0、Msxml2.DOMDocument 3.0为什么支持类似等于、不等于、大于这样的操作符,而无法识别contains这样的函数呢?直到我发现了这个方法:setProperty("SelectionLanguage", "XPath")。这时我恍然大悟,原来4.0以下版本的Msxml2.DOMDocument默认用类似正则匹配的方法来进行节点选取的,而4.0及以上版本默认采用Xpath作为默认的选择语言。
    我采用Msxml2.DOMDocument 2.0,将代码做以下修改也是可以正常运行的:

//aObjView_Xsf是存储上述Xml的文档对象
var aObjView_Xsf =new ActiveXObject('MSXML2.DOMDocument');
aObjView_Xsf.setProperty(
"SelectionLanguage""XPath");
aObjView_Xsf.setProperty(
"SelectionNamespaces","xmlns:xsf='http://schemas.microsoft.com/office/infopath/2003/solutionDefinition'");
aObjView_Xsf.load(
"test.xml");
var objerrorConditions = aObjView_Xsf.selectSingleNode("xsf:xDocumentClass/xsf:customValidation/xsf:errorCondition[@expressionContext!='"+strBinding+ "' and contains(xsf:subExpression,'"+fieldName+"')]");

 

抱歉!评论已关闭.