/* static */
void
txXPathNodeUtils::appendNodeValue(const txXPathNode& aNode, nsAString& aResult)
{
    if (aNode.isAttribute()) {
        const nsAttrName* name = aNode.Content()->GetAttrNameAt(aNode.mIndex);

        if (aResult.IsEmpty()) {
            aNode.Content()->GetAttr(name->NamespaceID(), name->LocalName(),
                                     aResult);
        }
        else {
            nsAutoString result;
            aNode.Content()->GetAttr(name->NamespaceID(), name->LocalName(),
                                     result);
            aResult.Append(result);
        }

        return;
    }

    if (aNode.isDocument() ||
        aNode.mNode->IsElement() ||
        aNode.mNode->IsNodeOfType(nsINode::eDOCUMENT_FRAGMENT)) {
        nsContentUtils::AppendNodeTextContent(aNode.mNode, true, aResult);

        return;
    }

    aNode.Content()->AppendTextTo(aResult);
}
/* static */
bool
txXPathNodeUtils::getAttr(const txXPathNode& aNode, nsIAtom* aLocalName,
                          PRInt32 aNSID, nsAString& aValue)
{
    if (aNode.isDocument() || aNode.isAttribute()) {
        return false;
    }

    return aNode.Content()->GetAttr(aNSID, aLocalName, aValue);
}
/* static */
nsresult
txXPathNodeUtils::getXSLTId(const txXPathNode& aNode,
                            nsAString& aResult)
{
    if (!aNode.isAttribute()) {
        CopyASCIItoUTF16(nsPrintfCString(kFmtSize, gPrintfFmt, aNode.mNode),
                         aResult);
    }
    else {
        CopyASCIItoUTF16(nsPrintfCString(kFmtSizeAttr, gPrintfFmtAttr,
                                         aNode.mNode, aNode.mIndex), aResult);
    }

    return NS_OK;
}
/* static */
nsresult
txXPathNodeUtils::getXSLTId(const txXPathNode& aNode,
                            const txXPathNode& aBase,
                            nsAString& aResult)
{
    uintptr_t nodeid = ((uintptr_t)aNode.mNode) - ((uintptr_t)aBase.mNode);
    if (!aNode.isAttribute()) {
        CopyASCIItoUTF16(nsPrintfCString(gPrintfFmt, nodeid),
                         aResult);
    }
    else {
        CopyASCIItoUTF16(nsPrintfCString(gPrintfFmtAttr,
                                         nodeid, aNode.mIndex), aResult);
    }

    return NS_OK;
}
/* static */
nsresult
txXPathNativeNode::getNode(const txXPathNode& aNode, nsIDOMNode** aResult)
{
    if (!aNode.isAttribute()) {
        return CallQueryInterface(aNode.mNode, aResult);
    }

    const nsAttrName* name = aNode.Content()->GetAttrNameAt(aNode.mIndex);

    nsAutoString namespaceURI;
    nsContentUtils::NameSpaceManager()->GetNameSpaceURI(name->NamespaceID(), namespaceURI);

    nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aNode.mNode);
    nsCOMPtr<nsIDOMAttr> attr;
    element->GetAttributeNodeNS(namespaceURI,
                                nsDependentAtomString(name->LocalName()),
                                getter_AddRefs(attr));

    return CallQueryInterface(attr, aResult);
}