ãã¾ã¾ã§æ¥æ¬èªã®APIããã¥ã¡ã³ããããã¨ããçç±ã§javax.xml.xpath.XPathã使ã£ã¦ããã®ã ããã©ããé£ã®èçã§ããã¨ããã®org.apache.xpath.XPathAPIãç°æ§ã«éãè¦ãã¦ä»æ¹ãªãã®ã§éãã調ã¹ã¦ã¿ãã
ä¸çªã®éãã¯ãåè
ã¯ãã¡ã¯ããªã¯ã©ã¹ã§çæãããªãã¸ã§ã¯ãã使ã£ã¦XPathå¼ãè©ä¾¡ããã®ã«å¯¾ããå¾è
ã¯ã¹ã¿ãã£ãã¯ã¡ã½ããã使ã£ã¦XPathå¼ãè©ä¾¡ããç¹ã ã¨æã£ãããã¨ã¯ã¡ã½ããã«æ¸¡ãå¼æ°ã®åã java.lang.Object
ã org.w3c.dom.Node
ãã®éãã¨ããè¿ã£ã¦ããã®ã java.lang.Object
ã org.w3c.dom.NodeList
ãã®éãã¨ããããªã¨ãããã¡ãã£ã¨ç´°ããè¦ã¦ãã£ã¦ã¿ããã
ããããXMLãå¦çããããã
<?xml version='1.0' encoding='UTF-8' ?>
<diary>
<title>ã¸ããªæ¥è¨</title>
<entry date="2007-05-04T20:46:02+09:00">
<title>æèµ·ãã¦å¤å¯ã</title>
<p>æèµ·ãããã©ããã ã®äººéã«ã¯èå³ããªãã®ã§å¤ã«å¯ãã</p>
</entry>
<entry date="2007-05-04T20:47:39+09:00">
<title>æé£ã¹ã¦å¤é£ã¹ã</title>
<p>æé£ã¹ããã©ãã¾ã ãã®åã«éãã¦ããªãã®ã§å¤ã«ãé£ã¹ãã</p>
</entry>
</diary>
ã©ã¡ãã®ã©ã¤ãã©ãªã使ãã«ãããã¾ãXMLããã¼ã¹ãã¦DOMã«ããã
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xml);
Element root = doc.getDocumentElement();
javax.xml.xpath.XPath
ã®å ´åã¯ãã¡ã¯ããªã¯ã©ã¹ã使ã£ã¦XPathãªãã¸ã§ã¯ããä½ãã
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
org.apache.xpath.XPathAPI
ã¯éçã¡ã½ãããå¼ã¶ã®ã§äºåæºåã¯ãªãã
åä¸ãã¼ãã®å¤ã®åå¾
diary
è¦ç´ ç´ä¸ã®title
è¦ç´ ã®å¤ãåå¾ãã¦ã¿ãã
javax.xml.xpath.XPath
ã®å ´åã¯evaluate
ã¡ã½ããã使ãã
System.out.println(xpath.evaluate("/diary/title", root));
org.apache.xpath.XPathAPI
ã®å ´åã¯eval
ã¡ã½ããã使ãã
System.out.println(XPathAPI.eval(root, "/diary/title"));
è¤æ°ãã¼ãã®ç¹°ãè¿ãå¦ç
åentry
è¦ç´ ã«ã¤ãã¦ããã®åè¦ç´ ã®p
è¦ç´ ã®å¤ãåå¾ãã¦ã¿ãã
javax.xml.xpath.XPath
ã®å ´åã¯evaluate
ã¡ã½ããã使ãã
NodeList entries = (NodeList) xpath.evaluate("/diary/entry", root, XPathConstants.NODESET);
for(int i = 0; i < entries.getLength(); i++) System.out.println(xpath.evaluate("p", entries.item(i)));
ãã£ã¹ããããªãã¨ãããªãã®ãé¢åããã¨ãevaluate
ã®ç¬¬3å¼æ°ã§è¿å´å¤ã®å¤ãæå®ããããããªããæåããéãååã®ã¡ã½ããã«ãã¦ããã°è¯ãã®ã§ã¯ãªãããããã¨ãXalanãåãåºãorg.w3c.dom.NodeList
ãªãã¸ã§ã¯ãã¯Iterable
ã®å®è£
ã§ã¯ãªãã®ã§ãæ¡å¼µForã«ã¼ãã使ããªããIterable
ã¨NodeList
ã®ä¸¡æ¹ãå®è£
ãããªãã¸ã§ã¯ããåãåºãã¦ãããXMLãã¼ãµãããã°ã¨ã£ã¦ãTigerã
åentry
è¦ç´ ãã¨ã«ä»ã«ãå¦çããããªãã¨ããããåã«p
è¦ç´ ã ããæãåºããããªãã以ä¸ã®ããã«ããã°XPathã®è©ä¾¡ã1åã ãã«ã§ããã
NodeList entries = (NodeList) xpath.evaluate("/diary/entry/p", root, XPathConstants.NODESET);
for(int i = 0; i < entries.getLength(); i++) System.out.println(entries.item(i).getFirstChild().getNodeValue());
org.apache.xpath.XPathAPI
ã®å ´åã¯selectNodeIterator
ã¡ã½ããã使ãã
NodeIterator it = XPathAPI.selectNodeIterator(root, "/diary/entry");
Node node;
while((node = it.nextNode())!=null) System.out.println(XPathAPI.eval(node, "p"));
selectNodeListã¡ã½ããã使ã£ã¦ãè¯ãããã®å ´åã¯javax.xml.xpath.XPathã¨å¤§ä½åãã
åå空éã¤ãã®XMLã®å ´å
ã¨ãããã¾ã§ã ã¨ãorg.apache.xpath.XPathAPI
ã®æ¹ã使ããããæãããããXPathã®ããã«æ°ãã«ãªãã¸ã§ã¯ããçæããå¿
è¦ããªãããã»ãããã¼ã¿åã«ãã£ã¦ä½¿ãã¡ã½ãããéã£ã¦ããæ¹ãã³ã¼ããèªã¿ããããããããä¾ã®XMLã«åå空éã宣è¨ããã¨ãã©ãããã¾ããããªããªãã®ã ã
以ä¸ã®ãããªåå空éä»ãã®XMLãå¦çããããã¨ãèããã
<?xml version='1.0' encoding='UTF-8' ?>
<diary xmlns="http://txqz.net/ns/diary#" xmlns:xh="http://www.w3.org/1999/xhtml">
<title>ã¸ããªæ¥è¨</title>
<entry date="2007-05-04T20:46:02+09:00">
<title>æèµ·ãã¦å¤å¯ã</title>
<xh:p>æèµ·ãããã©ããã ã®äººéã«ã¯èå³ããªãã®ã§å¤ã«å¯ãã</xh:p>
</entry>
<entry date="2007-05-04T20:47:39+09:00">
<title>æé£ã¹ã¦å¤é£ã¹ã</title>
<xh:p>æé£ã¹ããã©ãã¾ã ãã®åã«éãã¦ããªãã®ã§å¤ã«ãé£ã¹ãã</xh:p>
</entry>
</diary>
javax.xml.xpath.XPath
ã使ãå ´åã¯ãsetNamespaceContext
ã¡ã½ããã§åå空éãæå®ãããIBMã®è§£èª¬ãåèã«ãã¦ãjavax.xml.namespace.NamespaceContext
ãå®è£
ããã
import java.util.Iterator;
import java.util.Map;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
class NamespaceContextImpl implements NamespaceContext{
private Map<String,String> nsMap;
public NamespaceContextImpl(Map<String,String> nsMap){
this.nsMap = nsMap;
}
public String getNamespaceURI(String prefix) {
if(prefix == null) throw new NullPointerException("Null prefix");
if(nsMap.containsKey(prefix)) return nsMap.get(prefix);
return XMLConstants.NULL_NS_URI;
}
public String getPrefix(String uri) {
throw new UnsupportedOperationException();
}
public Iterator getPrefixes(String namespaceURI) {
throw new UnsupportedOperationException();
}
}
ã§ãXMLãèªãã¨ãã«;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
Element root = doc.getDocumentElement();
XPathFactory xFactory = XPathFactory.newInstance();
XPath xpath = xFactory.newXPath();
xpath.setNamespaceContext(getNamespaceContext(doc, "txqz"));
getNamespaceContext
ã¡ã½ããã®ä¸èº«ã¯ãããªæãã
private NamespaceContext getNamespaceContext(Document doc, String defaultPrefix){
Map<String,String> nsMap = new HashMap<String,String>();
Element root = doc.getDocumentElement();
NamedNodeMap attrs = root.getAttributes();
String xmlns = "xmlns";
for(int i = 0; i < attrs.getLength(); i++){
Node attr = attrs.item(i);
String[] name = attr.getNodeName().split(":");
if(xmlns.equals(name[0]))
nsMap.put(name.length == 1 ? defaultPrefix : name[1], attr.getNodeValue());
}
return new NamespaceContextImpl(nsMap);
}
ãã£ãã¨åããã¨ãããã«ã¯ä¸ã®ããã«åå空éæ¥é è¾ãã¤ããã°ããã
NodeList entries = (NodeList) xpath.evaluate("/txqz:diary/txqz:entry", root, XPathConstants.NODESET);
for(int i = 0; i < entries.getLength(); i++) System.out.println(xpath.evaluate("xh:p", entries.item(i)));
org.apache.xpath.XPathAPI
ã®åå空éä»ãXMLã®å¦çã«ã¯åé¡ããããããã¥ã¡ã³ããè¦ãã¨ãnamespaceNodeãããããorg.w3c.dom.Node
ãªãã¸ã§ã¯ãã第3å¼æ°ã«åãã¡ã½ããã¯ç¢ºãã«ç¨æããã¦ãããããã§ä»¥ä¸ã®ããã«æå®ãã¦ã¿ãããã¾ããããªãã
Node namespace = XPathAPI.selectSingleNode(root, "//namespace::xh");
System.out.println(XPathAPI.eval(root, "//xh:p[1]", namespace));
xhæ¥é è¾ãåå空éã«è§£æ±ºããã¦ããªãããã¨è¨ããã¦ãã¾ãã
Exception in thread "main" javax.xml.transform.TransformerException: Prefix must resolve to a namespace: xh
at org.apache.xpath.compiler.XPathParser.error(XPathParser.java:602)
at org.apache.xpath.compiler.Lexer.mapNSTokens(Lexer.java:674)
at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:397)
at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:139)
at org.apache.xpath.compiler.XPathParser.initXPath(XPathParser.java:143)
at org.apache.xpath.XPath.<init>(XPath.java:217)
at org.apache.xpath.XPathAPI.eval(XPathAPI.java:279)
at net.txqz.xpathapi.XPathAPITest.main(XPathAPITest.java:56)
ä¸å¿ãè¿°èªã使ãã°ãããããã¨ã¯ã§ããã
System.out.println(XPathAPI.eval(root, "//*[local-name()='p' and namespace-uri()='http://www.w3.org/1999/xhtml'][1]"));
ã§ããããã«ãé·ã£ããããã¦ããã¾ã使ããããªããå®æ°ã«ãã¦ãã¾ãæãããããã©ããããã
å°ã£ã¦æ¤ç´¢ãã¦ã¿ããXML & SOA ã«ããã£ã½ãæ¸ãè¾¼ã¿ããã£ãã
namespaceã¨ãã®prefixãè¨å®ããã«ã¯ã
PrefixResolver
ã¤ã³ã¿ã¼ãã§ã¤ã¹ãç¶æ¿ãã¦ãgetNamespaceForPrefix
ã¡ã½ãããå®è£ ãã¾ããããã¦ããããXPathAPIã«æ¸¡ãã¾ãã
ã¨ãããã¨ã§org.xml.utils.PrefixResolver
ãå®è£
ãã¦ä»¥ä¸ã®ãããªã¯ã©ã¹ãä½ã£ãã
import java.util.HashMap;
import java.util.Map;
import javax.xml.XMLConstants;
import org.apache.xml.utils.PrefixResolver;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
public class PrefixResolverImpl implements PrefixResolver {
private Map<String,String> nsMap;
public PrefixResolverImpl(Element root, String defaultPrefix){
nsMap = new HashMap<String,String>();
NamedNodeMap attrs = root.getAttributes();
String xmlns = "xmlns";
for(int i = 0; i < attrs.getLength(); i++){
Node attr = attrs.item(i);
String[] name = attr.getNodeName().split(":");
if(xmlns.equals(name[0]))
nsMap.put(name.length == 1 ? defaultPrefix : name[1], attr.getNodeValue());
}
}
public String getNamespaceForPrefix(String prefix) {
if(prefix == null) throw new NullPointerException("Null prefix");
if(nsMap.containsKey(prefix)) return nsMap.get(prefix);
return XMLConstants.NULL_NS_URI;
}
public String getNamespaceForPrefix(String arg0, Node arg1) {
throw new UnsupportedOperationException();
}
public String getBaseIdentifier() {
throw new UnsupportedOperationException();
}
}
å ã½ã¼ã¹ã¯ãããªæãã
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
Element root = doc.getDocumentElement();
PrefixResolver resolver = new PrefixResolverImpl(root, "txqz");
System.out.println(XPathAPI.eval(root, "/txqz:diary/txqz:entry/xh:p[1]",resolver));
ä¸å¿ããã§è¯ãã¿ããã ãã©ãé¢åããããã ãã常èçã«èãã¦â¦â¦ãã¦ãããä½ã§PrefixResolverãã¤ã³ããªã¡ã³ããããªãã¸ã§ã¯ããevalã¨ãã®ç¬¬3å¼æ°ã«å ¥ãããã®? ããã«å ¥ãã®ã¯Nodeãããªãã®? å²ãåããªããã®ãæãã¤ã¤ãã¨ãããããããããã§çµããã