Hatena::Groupmoz-addon

there.is.only.memo

 | 

2008-01-27

XPathGenerator

20:07

nsIXPathGeneratorノードXPath を簡単に取得することができます (xpath-generator 付きビルドが必要です)。

const Cc =Components.classes;
const Ci = Components.interfaces;

function getXPath(aNode, aContext) {
    var generator = Cc["@mozilla.org/xpath-generator;1"].createInstance(Ci.nsIXPathGenerator);
    try {
      var xpath = generator.generateXPath(aNode, aContext || aNode.ownerDocument);
    } catch (e) {
      return "";
    }
    return xpath;
}

例えば以下のようなドキュメントについて、考えてみます

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>XHTML + SVG</title>
</head>
<body>
    <p>XHTML + SVG</p>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="150px" height="150px"
        viewBox="0 0 100 100">
        <rect x="0" y="0" width="100" height="100" fill="none" stroke="black"/>
        <circle cx="50" cy="50" r="30" fill="red" />
    </svg>
    <p>XHTML + SVG!</p>
</body>
</html>

rect 要素の XPath を得たい時は以下のように使います。

var rect = document.getElementsByTagNameNS("http://www.w3.org/2000/svg", "rect")[0];
getXPath(rect, document);
// => a1:html/a1:body/a0:svg/a0:rect

名前空間接頭辞がわかりにくいので generateXPath() する前に addNamespace() で接頭辞を設定できます。

function getXPath(aNode, aContext) {
    var generator = Cc["@mozilla.org/xpath-generator;1"].createInstance(Ci.nsIXPathGenerator);
    // 名前空間に対する接頭辞を設定
    generator.addNamespace("http://www.w3.org/1999/xhtml", "html");
    generator.addNamespace("http://www.w3.org/2000/svg", "svg");
    //...
    try {
      var xpath = generator.generateXPath(aNode, aContext || aNode.ownerDocument);
    } catch (e) {
      return "";
    }
    return xpath;
}

上記の例だと、

var rect = document.getElementsByTagNameNS("http://www.w3.org/2000/svg", "rect")[0];
getXPath(rect, document);
// => html:html/html:body/svg:svg/svg:rect

という感じになります。

あと id 属性 *1 があると、デフォルトではそれ以上はたどりません。例えば、先ほどの例で body 要素の id 属性が foo だとすると、以下のようになります。

var rect = document.getElementsByTagNameNS("http://www.w3.org/2000/svg", "rect")[0];
getXPath(rect, document);
// => id('foo')/a0:svg/a0:rect

HTML 文書では、名前空間についてあれこれ考えなくても良いです。

<html>
<head>
    <title>An HTML document</title>
</head>
<body>
    <p>HTML</p>
    <p>HTML!</p>
</body>
</html>

2 つ目の p 要素に対してだと、

var p = document.getElementsByTagName("P")[1];
getXPath(p, document);
// => HTML/BODY/P[2]

という感じになります。

404 (Page Not Found) Error - Ever feel like you’re in the wrong place? では

var generator = new XPathGenerator();

でいけると書いてありますが、手元では失敗しました。

*1:厳密には isIdtrue な属性

DionDion2012/04/29 10:42Yeah, that's the tciket, sir or ma'am

awwazwavlawwazwavl2012/04/29 18:48KX6ezo <a href="http://njwviqmaqcfc.com/">njwviqmaqcfc</a>

xknqldoixknqldoi2012/04/29 23:33olsnYX , [url=http://thnucsymadtn.com/]thnucsymadtn[/url], [link=http://fkmowvcwrxot.com/]fkmowvcwrxot[/link], http://jsnvhbgizgyk.com/

bcxzxiefbcxzxief2012/04/30 22:32Q1q6Nl <a href="http://tscrscngdcnw.com/">tscrscngdcnw</a>

aonprhripqaonprhripq2012/05/02 14:43ApEwPe , [url=http://pgaedyxlvhky.com/]pgaedyxlvhky[/url], [link=http://lwrsiixnrlnn.com/]lwrsiixnrlnn[/link], http://ekenygcfpmzz.com/

 |