XPath:默认为“Master”节点,如果指定则选择当前节点(在第三个节点中)

时间:2013-07-02 15:47:31

标签: xpath conditional-operator infopath2010

我的问题:

  • 仅当“Sub_Node_Checker”设置为“false”时,才需要在“Master_Node”中选择值。
  • 如果“Sub_Node_Checker”设置为“true”,则该值必须设置为“Sub_Node”。
  • 当前节点为“Sub_Node”
  • 我正在使用InfoPath 2010。

以下是我的示例XML:

<my:myFields xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2013-07-02T14:58:05" xml:lang="en-us">
<my:Master_Node>123456</my:Master_Node>
<my:Repeater>
    <my:Sub_Node_Checker>false</my:Sub_Node_Checker>
    <my:Sub_Node></my:Sub_Node>
</my:Repeater>
</my:myFields>

请参阅the following forum thread下载我的XSN模板。

这是我一直尝试使用的XPath,但没有用(为了易读性添加了换行符):

//my:Master_Node[../my:Sub_Node_Checker = "false"] 
|
../my:Sub_Node[../my:Sub_Node_Checker = "true"]

这似乎没有任何回报,我不知道为什么。

以下问题伴随着我的XML格式中的“Sub_Node_Checker”:“子节点是否与主节点不同?”

  • 如果用户选择“是”(true),则应将Sub_Node字段设置为其自己的值。
  • 如果用户选择“否”(false),则Sub_Node字段应默认为Master_Node。

编辑&amp;其他XML

我的Repeater部分重复(根据名称)并且似乎会导致XPath选择器出现更多混乱。

<my:myFields xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2013-07-02T14:58:05" xml:lang="en-us">
<my:Master_Node>123123</my:Master_Node>
<my:Repeater>
    <my:Sub_Node_Checker>false</my:Sub_Node_Checker>
    <my:Sub_Node></my:Sub_Node>
</my:Repeater>
<my:Repeater>
    <my:Sub_Node_Checker>false</my:Sub_Node_Checker>
    <my:Sub_Node></my:Sub_Node>
</my:Repeater>
</my:myFields>

3 个答案:

答案 0 :(得分:1)

更清晰的解决方案是将谓词移动到<my:myFields/>元素。

/my:myFields[my:Repeater/my:Sub_Node_Checker = "false"]/my:Master_Node

如果你坚持自己的做法,那么你错过/来跳过<my:Repeater/>元素或引用:

//my:Master_Node[..//my:Sub_Node_Checker = "false"]
//my:Master_Node[../my:Repeater/my:Sub_Node_Checker = "false"]

答案 1 :(得分:1)

关于你的xpath问题,你可以尝试这样的事情。

(self::*[../my:Sub_Node_Checker = "true"] 
|
//my:Master_Node)[last()]

如果Master_Node始终在Sub_Node之前(按文档顺序排列),哪个应该有效。

答案 2 :(得分:1)

好的,我得到的这个与我原来的方法有点不同。 The following article on MSDN有一个使用substring()函数根据外部条件返回不同值的示例。还要感谢InfoPath Dev的Hilary Stoupa helping me come to the solution

我还要提到我无法使用“当前”节点并且必须创建第三个节点,该节点包含我的XPath表达式并评估条件以返回适当的值。

这是源XML,大致与InfoPath可能会解释它一样(请注意第3 repeater组中xpath表达式的“位置” - 这是InfoPath评估默认值的方式):

<my:myFields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2013-07-02T14:58:05" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xml:lang="en-us">
<my:Master_Node>123456</my:Master_Node>
<my:Repeater>
    <my:Sub_Node_Checker>true</my:Sub_Node_Checker>
    <my:Sub_Node>9870</my:Sub_Node>
    <my:Sub_Node_Stored>9870</my:Sub_Node_Stored>
</my:Repeater>
<my:Repeater>
    <my:Sub_Node_Checker>false</my:Sub_Node_Checker>
    <my:Sub_Node></my:Sub_Node>
    <my:Sub_Node_Stored>123456</my:Sub_Node_Stored>
</my:Repeater><
my:Repeater>
    <my:Sub_Node_Checker>false</my:Sub_Node_Checker>
    <my:Sub_Node></my:Sub_Node>
    <my:Sub_Node_Stored>concat(substring(../../my:Master_Node, 1, (../my:Sub_Node_Checker != "true") * string-length(../../my:Master_Node)), substring(../my:Sub_Node, 1, (../my:Sub_Node_Checker != "false") * string-length(../my:Sub_Node)))</my:Sub_Node_Stored>
</my:Repeater>
</my:myFields>

请注意,以下XPath表达式有助于选择适当的节点:

concat(substring(../../my:Master_Node, 1, (../my:Sub_Node_Checker != "true") * string-length(../../my:Master_Node)), substring(../my:Sub_Node, 1, (../my:Sub_Node_Checker != "false") * string-length(../my:Sub_Node)))

substring函数返回用户指定的目标字符串中的字符数。当在子字符串函数内(在给出要返回的字符数的位置)评估布尔值时,它返回“1”或“0”。

当乘以目标字符串的长度时,此布尔检查会导致任何使特定目标节点无法选择的条件从该节点返回“0”字符的长度。 (0 * X = 0)这有效地允许节点内的不同默认值,而无需使用|运算符。