【问题标题】:Javascript XPath table loop td'sJavascript XPath 表循环 td
【发布时间】:2020-06-06 18:55:26
【问题描述】:

我正在尝试创建一个 Chrome 扩展程序,该扩展程序将从表中提取一些数据。我想将 TR 的 TD 转换为简单的行,每列由管道 | 字符分隔,例如:

01/01/2020 | XX | 57,43 | |
02/01/2020 | YY | 11,22 | |

这是其中的一部分:

<table width="100%" border="0" cellpadding="2" cellspacing="0">
    <tbody>
        <tr>
            <td class="TRNbarratabelac" width="3%">
                <input type="checkbox" name="chkTodos" id="chkTodos" onclick="selTodos(this)" style="background:transparent;border:0px;"></td>
            <td class="TRNbarratabelac">Data do <br>pagamento</td>
            <td class="TRNbarratabelac">Tipo</td>
            <td class="TRNbarratabelac">Favorecido/beneficiário</td>
            <td class="TRNbarratabelac">Valor (R$)</td>
            <td class="TRNbarratabelac">Informações complementares</td>
            <td class="TRNbarratabelac" colspan="2" width="20%">Opções</td>
        </tr>
        <tr>
            <td class="TRNlicbe"><input type="checkbox" name="chkSel" id="chkSel" value="1" onclick="verSelTodos(this)" style="background:transparent;border:0px;"></td>
            <td class="TRNlicbe">21/02/2020&nbsp;</td>
            <td class="TRNliebe">Concessionárias</td>
            <td class="TRNliebe"> &nbsp;</td>
            <td class="TRNlidbe">57,43&nbsp;</td>
            <td class="TRNlicbe"> &nbsp;</td>
            <td class="TRNlicbde" width="8%"><a href="javascript:detalharIndividual('1')" class="lnkpadrao01">Visualizar</a></td>
            <td class="TRNlicbde" width="12%"><span><a href="javascript:email('1')" class="lnkpadrao01">enviar por email</a></span>&nbsp;</td>
        </tr>
    </tbody>
</table>

为了对其进行迭代,我使用这样的 XPath:

function DOMtoString(doc) {

    let path_tr = '(//div[@class="contborda"])[4]/table[3]/tbody/tr[position()>1]';
    var tr = doc.evaluate(path_tr, doc, null, XPathResult.ANY_TYPE, null);    

    let alertText = '';

    let x = tr.iterateNext(); 

    while (x) {
        alertText += x.textContent;
        x = tr.iterateNext();
    }

    return alertText;
}

在这里我得到了表格(忽略第一个带有列名的 TR),但结果是这样的(只是其中的一部分):

<br>   <br>   21/02/2020&nbsp;<br>   Concessionárias<br>    &nbsp;<br>   57,43&nbsp;<br>    &nbsp;<br>   Visualizar<br>   enviar por email&nbsp;<br><br>   

我看到 XPath 正在为其添加 BR。

我尝试循环遍历这些 TR 的 TD,但没有成功:

let path_td = '//td';
var td = tr.evaluate(path_td, tr, null, XPathResult.ANY_TYPE, null);

我可以通过 TD 进行交互并在没有 BR 的情况下获取它们的原始文本的正确方法是什么?

【问题讨论】:

  • 为什么选择使用 XPath 而不是 Document.querySelector()
  • @ChristosLytras 好问题...我没有表格 ID 或任何可以找到表格的 CSS 类...或者有什么办法吗?从未使用过 QuerySelector
  • 它比 XPath 更容易。我会使用选择器给你写一个答案,然后你告诉我你的想法。

标签: javascript html dom xpath google-chrome-extension


【解决方案1】:

使用innerText 而不是textContent 以避免换行。您可以使用 Document.querySelector() 代替 XPath,这将使 DOM 操作更加容易。

CSS 选择器:

function DOMtoString() {
  let lines = [];
  let trs = document.querySelectorAll(
    'div.contborda > table:nth-of-type(2) > tbody > tr:not(:first-child)'
  );
  
  trs.forEach(tr => {
    let line = [];
    let tds = tr.querySelectorAll('td');
    
    tds.forEach(td => line.push(td.innerText.trim()));
  	lines.push(line.join('|'));
  });
  
  return lines;
}

console.log(DOMtoString());
<div class="dummy"></div>

<div class="contborda">
<table class="dummy"><tbody></tbody></table>

<table width="100%" border="0" cellpadding="2" cellspacing="0">
    <tbody>
        <tr>
            <td class="TRNbarratabelac" width="3%">
                <input type="checkbox" name="chkTodos" id="chkTodos" onclick="selTodos(this)" style="background:transparent;border:0px;"></td>
            <td class="TRNbarratabelac">Data do <br>pagamento</td>
            <td class="TRNbarratabelac">Tipo</td>
            <td class="TRNbarratabelac">Favorecido/beneficiário</td>
            <td class="TRNbarratabelac">Valor (R$)</td>
            <td class="TRNbarratabelac">Informações complementares</td>
            <td class="TRNbarratabelac" colspan="2" width="20%">Opções</td>
        </tr>
        <tr>
            <td class="TRNlicbe"><input type="checkbox" name="chkSel" id="chkSel" value="1" onclick="verSelTodos(this)" style="background:transparent;border:0px;"></td>
            <td class="TRNlicbe">21/02/2020&nbsp;</td>
            <td class="TRNliebe">Concessionárias</td>
            <td class="TRNliebe"> &nbsp;</td>
            <td class="TRNlidbe">57,43&nbsp;</td>
            <td class="TRNlicbe"> &nbsp;</td>
            <td class="TRNlicbde" width="8%"><a href="javascript:detalharIndividual('1')" class="lnkpadrao01">Visualizar</a></td>
            <td class="TRNlicbde" width="12%"><span><a href="javascript:email('1')" class="lnkpadrao01">enviar por email</a></span>&nbsp;</td>
        </tr>
    </tbody>
</table>
</div>

如果您有任何其他原因想要坚持使用 XPath,那么当您想要选择相对于 nodeContext 的节点时,您应该使用点 .//

XPath:

function DOMtoString() {
  let lines = [];
  
  let path_tr = '//div[@class="contborda"]/table/tbody/tr[position()>1]';
  let tr = document.evaluate(path_tr, document, null, XPathResult.ANY_TYPE, null);    

  let x = tr.iterateNext(); 

  while (x) {
      let line = [];

      let path_td = './/td';
      var td = document.evaluate(path_td, x, null, XPathResult.ANY_TYPE, null);

      let y = td.iterateNext();
      
      while (y) {
        line.push(y.innerText.trim());
        y = td.iterateNext();
      }
      
      lines.push(line.join('|'));
      x = tr.iterateNext();
  }

  return lines;
}

console.log(DOMtoString());
<div class="dummy"></div>

<div class="contborda">
<table class="dummy"><tbody></tbody></table>

<table width="100%" border="0" cellpadding="2" cellspacing="0">
    <tbody>
        <tr>
            <td class="TRNbarratabelac" width="3%">
                <input type="checkbox" name="chkTodos" id="chkTodos" onclick="selTodos(this)" style="background:transparent;border:0px;"></td>
            <td class="TRNbarratabelac">Data do <br>pagamento</td>
            <td class="TRNbarratabelac">Tipo</td>
            <td class="TRNbarratabelac">Favorecido/beneficiário</td>
            <td class="TRNbarratabelac">Valor (R$)</td>
            <td class="TRNbarratabelac">Informações complementares</td>
            <td class="TRNbarratabelac" colspan="2" width="20%">Opções</td>
        </tr>
        <tr>
            <td class="TRNlicbe"><input type="checkbox" name="chkSel" id="chkSel" value="1" onclick="verSelTodos(this)" style="background:transparent;border:0px;"></td>
            <td class="TRNlicbe">21/02/2020&nbsp;</td>
            <td class="TRNliebe">Concessionárias</td>
            <td class="TRNliebe"> &nbsp;</td>
            <td class="TRNlidbe">57,43&nbsp;</td>
            <td class="TRNlicbe"> &nbsp;</td>
            <td class="TRNlicbde" width="8%"><a href="javascript:detalharIndividual('1')" class="lnkpadrao01">Visualizar</a></td>
            <td class="TRNlicbde" width="12%"><span><a href="javascript:email('1')" class="lnkpadrao01">enviar por email</a></span>&nbsp;</td>
        </tr>
    </tbody>
</table>
</div>

【讨论】:

    猜你喜欢
    • 2021-07-13
    • 2015-06-22
    • 1970-01-01
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多