【问题标题】:Differences in Xpath evalution between Chrome and FirefoxChrome 和 Firefox 之间 Xpath 评估的差异
【发布时间】:2016-06-22 09:40:43
【问题描述】:

目标:尝试通过提供表索引、列标题和行号从第 n 个表中选择一个单元格。我的 xpath 在 Firefox 中有效,但在 Chrome 中无效。

相同的 xpath 在 Firefox 中有效,但在 Chrome 中无法评估。

xpath 正在尝试使用列标题选择表格中的单元格。

可在 Firefox 中使用,但不能在 Chrome 中使用

(//table)[count((//table)[5]/descendant::th)]

Firefox,根据表 5 的列数返回该表,但 Chrome 不返回任何内容。

((//table)[2]/tbody/tr[1]/td)[count((//table)[2]/descendant::th[.='TextField']/preceding-sibling::th)+1]

Firefox 返回“TextField”列第一行的单元格,Chrome 不返回任何内容。

我正在使用的 html 有点像 div 汤,​​如下所示。尝试在 Chrome 和 Firefox 中运行 sn-p,结果会有所不同(运行 sn-p 并一直向下滚动可以找到)。

// Print title
document.body.insertAdjacentHTML('beforeEnd', '<h2>Table Query Results<\/h2>');
// Evaluate the xpath
var resultTable = document.evaluate("(//table)[count((//table)[2]/descendant::th)-3]", document, null, XPathResult.ANY_TYPE, null);
var resultTableVal = null;
// If the xpath returned a result, grab the first result
if (resultTable != null) resultTableVal = resultTable.iterateNext();
// If both the xpath result and first result have values
if (resultTable != null && resultTableVal != null) {
  // Create a pre tag
  var preTable = document.createElement('pre');
  // While there are results
  while (resultTableVal) {
    // Add them to pre
    preTable.textContent += 'Found ' + resultTableVal.outerHTML + '\n';
    resultTableVal = resultTable.iterateNext();
  }
  document.body.appendChild(preTable);
}
else {
  document.body.insertAdjacentHTML('beforeEnd', '<p>No node found.<\/p>');
}

document.body.insertAdjacentHTML('beforeEnd', '<h2>Cell Query Results<\/h2>');
var resultCell = document.evaluate("((//table)[2]/tbody/tr[1]/td)[count((//table)[2]/descendant::th[.='TextField']/preceding-sibling::th)+1]", document, null, XPathResult.ANY_TYPE, null);
var resultCellVal = null;
if (resultCell != null) resultCellVal = resultCell.iterateNext();
if (resultCell != null && resultCellVal != null) {
  var preCell = document.createElement('pre');
  while (resultCellVal) {
    preCell.textContent += 'Found ' + resultCellVal.outerHTML + '\n';
    resultCellVal = resultCell.iterateNext();
  }
  document.body.appendChild(preCell);
}
else {
  document.body.insertAdjacentHTML('beforeEnd', '<p>No node found.<\/p>');
}
table { border: 1px solid black; }
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <div>
    <div>
      <h3>Grids</h3>
      <div></div>
      <div></div>
    </div>
    <div></div>
    <div>
      <div>
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>
                      <div>
                        <span>EditableGrid</span><em>*</em>
                      </div>
                      <div>
                        <p></p>
                      </div>
                      <div>
                        <div>
                          <table>
                            <colgroup>
                              <col>
                              <col>
                              <col>
                              <col>
                              <col>
                              <col>
                              <col>
                            </colgroup>
                            <thead>
                              <tr>
                                <th>
                                  <div>
                                    <h2>TextField</h2><a><i></i></a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>ParagraphField</h2><a><i></i></a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>EncryptedTextField</h2><a><i></i</a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>IntegerField</h2><a><i></i></a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>DecimalField</h2><a><i></i></a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>DateField</h2><a><i></i></a>
                                  </div>
                                </th>
                              </tr>
                            </thead>
                            <tbody>
                              <tr>
                                <td>
                                  <div>
                                    <div>
                                      <div>
                                        <span><em>*</em>
                                        <label>Label</label></span>
                                        <div>
                                          <div>
                                            Text Input
                                          </div>
                                        </div>
                                        <div>
                                          <p></p>
                                        </div>
                                        <div></div>
                                        <div></div>
                                      </div>
                                    </div>
                                  </div>
                                </td>
                                <td>
                                  <div>
                                    <div>
                                      <div>
                                        <span><em>*</em>
                                        <label>Label</label></span>
                                        <div>
                                          <div>
                                            Paragraph input
                                          </div>
                                        </div>
                                        <div>
                                          <p></p>
                                        </div>
                                        <div></div>
                                        <div></div>
                                      </div>
                                    </div>
                                  </div>
                                </td>
                                <td>
                                  <div>
                                    <div>
                                      <div>
                                        <span><em>*</em>
                                        <label>Label</label></span>
                                        <div>
                                          <div>
                                            Encrypted Text input
                                          </div>
                                        </div>
                                        <div>
                                          <p></p>
                                        </div>
                                        <div></div>
                                        <div></div>
                                      </div>
                                    </div>
                                  </div>
                                </td>
                                <td>
                                  <div>
                                    <div>
                                      <div>
                                        <span><em>*</em>
                                        <label>Label</label></span>
                                        <div>
                                          <div>
                                            Integer Input
                                          </div>
                                        </div>
                                        <div>
                                          <p></p>
                                        </div>
                                        <div></div>
                                        <div></div>
                                      </div>
                                    </div>
                                  </div>
                                </td>
                                <td>
                                  <div>
                                    <div>
                                      <div>
                                        <span><em>*</em>
                                        <label>Label</label></span>
                                        <div>
                                          <div>
                                            Decimal input
                                          </div>
                                        </div>
                                        <div>
                                          <p></p>
                                        </div>
                                        <div></div>
                                        <div></div>
                                      </div>
                                    </div>
                                  </div>
                                </td>
                                <td>
                                  <div>
                                    <div>
                                      <div>
                                        <span><em>*</em>
                                        <label>Label</label></span>
                                        <div>
                                          <div>
                                            <div>
                                              Date input
                                            </div>
                                          </div>
                                        </div>
                                        <div>
                                          <p></p>
                                        </div>
                                        <div></div>
                                        <div></div>
                                      </div>
                                    </div>
                                  </div>
                                </td>
                              </tr>
                            </tbody>
                          </table>
                        </div>
                      </div>
                      <div></div>
                    </div>
                  </div>
                </div>
                <div>
                  <div>
                    <div>
                      <div>
                        <span>ReadOnlyGrid</span><em>*</em>
                      </div>
                      <div>
                        <p></p>
                      </div>
                      <div>
                        <div>
                          <table>
                            <colgroup>
                              <col>
                              <col>
                              <col>
                              <col>
                              <col>
                              <col>
                            </colgroup>
                            <thead>
                              <tr>
                                <th>
                                  <div>
                                    <h2>TextField</h2><a><i></i></a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>ParagraphField</h2><a><i></i></a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>EncryptedTextField</h2><a><i></i>/a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>IntegerField</h2><a><i></i></a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>DecimalField</h2><a><i></i></a>
                                  </div>
                                </th>
                                <th>
                                  <div>
                                    <h2>DateField</h2><a><i></i></a>
                                  </div>
                                </th>
                              </tr>
                            </thead>
                            <tfoot></tfoot>
                            <tbody>
                              <tr>
                                <td>Column1</td>
                                <td>Column2</td>
                                <td>Column3</td>
                                <td>Column4</td>
                                <td>Column5</td>
                                <td>Column6</td>
                              </tr>
                            </tbody>
                          </table>
                        </div>
                      </div>
                      <div></div>
                    </div>
                  </div>
                </div>
                <div>
                  <div>
                    <div>
                      <span>EditableGrid</span><em>*</em>
                    </div>
                    <div>
                      <p></p>
                    </div>
                    <div>
                      <div>
                        <table>
                          <colgroup>
                            <col>
                            <col>
                            <col>
                            <col>
                          </colgroup>
                          <thead>
                            <tr>
                              <th>
                                <div>
                                  <h2>PickerField1</h2><a><i></i></a>
                                </div>
                              </th>
                              <th>
                                <div>
                                  <h2>PickerField2</h2><a><i></i></a>
                                </div>
                              </th>
                              <th>
                                <div>
                                  <h2>PickerField3</h2><a><i></i></a>
                                </div>
                              </th>
                              <th>
                                <div>
                                  <h2>PickerField4</h2><a><i></i></a>
                                </div>
                              </th>
                            </tr>
                          </thead>
                          <tfoot></tfoot>
                          <tbody>
                            <tr>
                              <td>Userpick data</td>
                              <td>Grouppicker data</td>
                              <td>User group picker data</td>
                              <td>Document picker</td>
                            </tr>
                            <tr>
                              <td>Folder Picker</td>
                              <td>Document folder picker</td>
                              <td>Custom picker</td>
                              <td><span>*</span></td>
                            </tr>
                          </tbody>
                        </table>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

【问题讨论】:

    标签: google-chrome firefox xpath


    【解决方案1】:

    尝试用(//table)[count((//table)[5]/descendant::th)]重现问题:

    var result = document.evaluate('(//table)[count((//table)[5]/descendant::th)]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
    if (result != null) {
      var pre = document.createElement('pre');
      pre.textContent = 'Found ' + result.outerHTML;
      document.body.appendChild(pre);
    }
    else {
      document.body.insertAdjacentHTML('beforeEnd', '<p>No node found.<\/p>');
    }
    table { border: 1px solid black; }
    <table id="t1">
      <tbody>
        <tr>
          <td>table 1</td>
        </tr>
      </tbody>
    </table>
    
    <table id="t2">
      <tbody>
        <tr>
          <td>table 2</td>
        </tr>
      </tbody>
    </table>
    
    <table id="t3">
      <tbody>
        <tr>
          <td>table 3</td>
        </tr>
      </tbody>
    </table>
    
    <table id="t4">
      <tbody>
        <tr>
          <td>table 4</td>
        </tr>
      </tbody>
    </table>
    
    <table id="t5">
      <thead>
        <tr>
          <th>table 5 header </th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>table 5</td>
        </tr>
      </tbody>
    </table>

    我在 Firefox、Edge 和 Chrome 上得到了相同的结果,第一个表被选中,因为第五个表有一个 th 元素。考虑编辑您的问题并插入代码 sn-ps 以便我们重现问题。

    【讨论】:

    • 好吧,我花了一段时间(第一次问问题),但我已经在你的模板之后添加了一个 sn-p,如果你在 chrome 和 firefox 上运行它,你会看到我的结果指的是。
    • 很好,就我用var resultTable = document.evaluate("(//table)[count((//table)[2]/descendant::th)-3]", document, null, XPathResult.ANY_TYPE, null); 检查 Chrome 结果而言,这是一个明显的错误,因此您可能需要报告该错误。第二个看起来也像一个错误,因为 Edge 和 Firefox 都找到了一个单元格,尽管我没有检查所有细节。再次向 Google 报告。
    • 我确实通过 chrome 应用进行了报告,只是想知道是否有其他解决方法可以适用于所有浏览器。
    • @MichaelChirlin - 我找不到你的问题(我可能没有必要的权限) - 如果你找不到类似的现有问题,你可以在crbug.com 提交它吗?这样,这将是一个公共问题,其他人可以跟随它取得进展。谢谢!
    • @PhistucK,我最初是通过 Chrome 浏览器“报告和问题”提交的。但现在我已将其提交为Chromium bug