XPathExpression, XPathResultのサンプル

サンプル1

買った物リスト
買った物 単価(円) 数量(個)
ボールペン 100 5
うまい棒 10 20
豚肉 398 2

ソース1

<table frame="box">
<caption>買った物リスト</caption>
<tr>
<th class="item">買った物</th>
<th class="unityen">単価(円)</th>
<th class="count">数量(個)</th>
</tr>
<tr>
<td class="item">ボールペン</td>
<td class="unityen">100</td>
<td class="count">5</td>
</tr>
<tr>
<td class="item">うまい棒</td>
<td class="unityen">10</td>
<td class="count">20</td>
</tr>
<tr>
<td class="item">豚肉</td>
<td class="unityen">398</td>
<td class="count">2</td>
</tr>
</table>
if(document.implementation.hasFeature("xpath","3.0")){
  var contextNode = document.documentElement;
  var resolver = document.createNSResolver(contextNode);
}

function calctotal(){
  if(document.implementation.hasFeature("xpath","3.0")){
    var cntexp = 'sum(//table//tr/td[@class="count"]/text())';
    var cntsum = document.evaluate(cntexp, contextNode, resolver, XPathResult.NUMBER_TYPE, null);
    alert("数量合計:"+cntsum.numberValue+"点");
    
    var uyexp = '//table//tr/td[@class="unityen"]/text()';
    var cntexp = '//table//tr/td[@class="count"]/text()';
    var type_itr = XPathResult.ORDERED_NODE_ITERATOR_TYPE;
    var uyitr = document.evaluate(uyexp, contextNode, resolver, type_itr, null);
    var cntitr = document.evaluate(cntexp, contextNode, resolver, type_itr, null);
    var sum = 0;
    var uynode, cntnode;
    while( (uynode=uyitr.iterateNext())&&(cntnode=cntitr.iterateNext()) ){
      sum += parseInt(uynode.nodeValue) * parseInt(cntnode.nodeValue)
    }
    alert("金額合計:"+sum+"円");
  }
}
function chengepork(){
  if(document.implementation.hasFeature("xpath","3.0")){
    var porkyenexp = '//table//tr[string(td[@class="item"]/text())="豚肉"]/td[@class="unityen"]/text()';
    var porkyennode = document.evaluate(porkyenexp, contextNode, resolver, XPathResult.ANY_UNORDERED_NODE_TYPE, null);
    porkyennode.singleNodeValue.nodeValue = '348';
  }
}

この少ない行数でややこしいことを書けるのがXPathの魅力だと思います。同じことをDOM Level 1で書くとどうなるやら(特に後者)。