如何在FreeMarker中获取节点的XPath。我想知道联轴器。例如,如果我正在处理一个节点,并希望以XML格式获取它的地址。
类似于: node?node_xpath。
发布于 2012-01-30 20:44:37
这样的事情不存在于盒子之外。您可以为它编写一个自定义方法(TemplateMethodModelEx实现)。你到底需要什么样的路径呢?像/node()[0]/node()[3]/node()[2]这样的?我相信W3C DOM没有方法来查询节点的索引,所以您必须扫描节点的父节点的子节点来查找它的索引。(这是DOM限制,而不是FreeMarker限制。)或者,如果您对模式有更多的了解,您可能想要像/foo/bar[@id=123]/baaz这样的函数,但显然这不是一个通用的函数。
发布于 2012-09-08 04:06:25
试试这个:
public class GetXPathFromNode implements TemplateMethodModelEx {
public Object exec(List args) throws TemplateModelException {
if(args.size() != 1){
throw new TemplateModelException("Please specify one xml node.");
}
NodeModel node = (NodeModel) args.get(0);
return getXPath(node.getNode());
}
private String getXPath(Node node) {
StringBuilder sb = new StringBuilder("/");
String attribute = "";
if(node.getNodeType() == Node.ATTRIBUTE_NODE){
attribute = "/@" + node.getNodeName();
Attr attr = (Attr) node;
node = attr.getOwnerElement();
}
sb.append(node.getNodeName())
.append("[").append(getNodeIndex(node)).append("]").append(attribute);
return renderNodeXpath(node, sb).toString();
}
private StringBuilder renderNodeXpath(Node node, StringBuilder path){
Node parentNode = node.getParentNode();
if(parentNode != null && parentNode.getNodeType() != Node.DOCUMENT_NODE){
StringBuilder sb2 = new StringBuilder("/");
sb2.append("[").append(getNodeIndex(parentNode)).append("]");
path.insert(0,sb2);
return renderNodeXpath(parentNode, path);
}
return path;
}
private int getNodeIndex(Node childNode) {
Node parentNode = childNode.getParentNode();
if(parentNode == null){
return 1;
}
int index = 1;
for(int i = 0; parentNode.getChildNodes().getLength() >= i; i++){
Node node = parentNode.getChildNodes().item(i);
if(node.isSameNode(childNode)){
return index; // this is used to ignore empty text nodes.
}
if(node.getNodeType() != Node.TEXT_NODE){
index++;
}
}
return 1;
}
}https://stackoverflow.com/questions/9062331
复制相似问题