JAvaとXml
Javaは主にDOM(最も一般的)、SAX(最も効率的)、XPath(最も直接的)の3つのXMLの解析とノード遍歴モデルを提供している.ここでは,主に2つのモデルDOMとXPathについて実例による一歩一歩理解する.
1. 最も簡単なXML:
2. DOMモデルを介してXMLのすべてのノードを比較的完全に巡回する例:
3. XMLのノードにアクセスするには、XPathを使用します. XPath言語の基本的な構文は次のとおりです. 1) /gridbag/row:ルート要素gridbagのサブ要素のすべてのrow要素を表します. 2) /gridbag/row[1]:[]を使用して、最初のサブエレメントを選択するエレメントのセットの特定のエレメントを選択します. 3) /gridbag/row[1]/cell[1]/@anchor:最初の行の最初のセルのanchorプロパティを説明します. 4) /gridbag/row/cell/@anchor:ルート要素gridbagのサブ要素である行要素のすべてのセルのanchorプロパティノードを記述します. 5) count(/gridbag/row):XPathはcountなどの有用な関数も提供します. Java SE 5にAPIを追加してXPath式を計算するには、XPathFactoryからXPathオブジェクトを作成する必要があります.たとえば、次のようにします. XPathFactory xpFactory = XPathFactory.newInstance(); XPath path = xpFactory.newXPath(); 次にevaluateメソッドを呼び出してXPath式を計算します.たとえば、次のようになります. String username = path.evaluate("/gridbag/row[1]/@anthor",doc); この形式のevaluate()メソッドは、文字列を返します.また、次のようなサブノードのセットを返します. NodeList nodes = path.evaluate("/gridbag/row",doc,XPathConstants.NODESET); ノードが1つしかない場合は、次のようにNODESETの代わりにNODE定数を使用できます. Node node = path.evaluate("/gridbag/row[1]",doc,XPathConstants.NODE); 結果が数値の場合は、次のようなXPathConstants.NUMBERを使用します. int count = ((Number)path.evaluate("count(/gridbag/row)",doc,XPathConstants.NUMBER)).intValue(); 次のコードは、XPathクエリXMLに基づいて一般的に使用されているコードのみをリストします.
4. XMLのDOMモデルを構築し、DOMTreeModelをXMLファイルに出力します.
1. 最も簡単なXML:
- //1. Element TagName( ) 。
- // Element 。
- //2. <RootElement>、<FirstElement> <SecondElement> Element。
- //3. "I am the first Node" "I am the second Node" Text。
- // Test.xml
- //<RootElement>
- // <FirstElement>I am the first Node</FirstElement>
- // <SecondElement>I am the second Node</SecondElement>
- //</RootElement>
- public static void main(String[] args) {
- // DocmentBuilderFactory
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- // DocumentBuilder
- DocumentBuilder builder = null;
- try {
- builder = factory.newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- }
- // Document
- Document doc = null;
- try {
- doc = builder.parse(new File("D:/test.xml"));
- } catch (SAXException e) {
- } catch (IOException e) {
- }
-
- NodeList nl = doc.getElementsByTagName("RootElement");
- for (int i = 0; i < nl.getLength(); i++) {
- Element e = (Element) nl.item(i);
- System.out.println(e.getElementsByTagName("FirstElement").item(0)
- .getFirstChild().getNodeValue());
- System.out.println(e.getElementsByTagName("SecondElement")
- .item(0).getFirstChild().getNodeValue());
- }
- }
- //1. Element ,
- // Element ,
- // 。
- //2. Node (Node ), node.getNodeType()
- // Node , Node.ELEMENT_NODE、Node.ATTRIBUTE_NODE 。
- // Test.xml
- //<RootElement>
- // <FirstElement>I am the first Node</FirstElement>
- // <SecondElement>I am the second Node</SecondElement>
- //</RootElement>
- public static void main(String[] args) {
- String filename = "D:/Test.xml";
- try {
- System.out.println(filename + " elementCount: " + getElementCount(filename));
- } catch (Exception e) {
- }
- }
- /* getElementCount(Node),Node */
- public static int getElementCount(String fileName) throws Exception {
- Node node = readFile(new File(fileName));
- return getElementCount(node); // Elements
- }
- /* , Document */
- public static Document readFile(File file) throws Exception {
- Document doc;
- try {
- /* DocumentBuilderFactory */
- DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
- /* DocumentBuilder */
- DocumentBuilder db = dbf.newDocumentBuilder();
- /* */
- doc = db.parse(file);
- /* Document */
- return doc;
- } catch (SAXParseException ex) {
- throw (ex);
- } catch (SAXException ex) {
- Exception x = ex.getException(); // get underlying Exception
- throw ((x == null) ? ex : x);
- }
- }
- /*
- * DOM ELEMENTS
- */
- public static int getElementCount(Node node) {
- /* node , 0 */
- if (null == node)
- return 0;
- int sum = 0;
- // , , ELEMENT
- boolean isElement = (node.getNodeType() == Node.ELEMENT_NODE);
- // ELEMENT , sum 1
- if (isElement)
- sum = 1;
- //
- NodeList children = node.getChildNodes();
- // ,
- if (null == children)
- return sum;
- //
- for (int i = 0; i < children.getLength(); i++)
- sum += getElementCount(children.item(i));
- return sum;
- }
2. DOMモデルを介してXMLのすべてのノードを比較的完全に巡回する例:
- public class MyTest {
- //
- // , hardcode, XML 。
- //<attributes>
- // <!--Comment1-->
- // <attribute1 name="Technology" type="C" size="100" allow_multi_val="N" />
- // <attribute2 name="Mfg_Area" type="C" size="100" allow_multi_val="N" />
- // <attribute3 name="Product_Family" type="C" size="100" allow_multi_val="N"/>
- // <![CDATA[ cdatatest1 ]]>
- // <attributeWithText>This is test data</attributeWithText>
- //</attributes>
- public static void main(String[] args) {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setIgnoringElementContentWhitespace(true);
- // DocumentBuilder
- DocumentBuilder builder = null;
- try {
- builder = factory.newDocumentBuilder();
- } catch (ParserConfigurationException e) {
- }
- ByteArrayOutputStream bout = new ByteArrayOutputStream(512);
- PrintStream ps = new PrintStream(bout);
- ps.println("<attributes>");
- ps.println("<!--Comment1-->");
- ps.println("<![CDATA[ cdatatest1 ]]>");
- ps.println("<attribute1 name=\"Technology\" type=\"C\" " +
- "size=\"100\" isnull=\"true\" allow_multi_val=\"N\" />");
- ps.println("<attribute2 name=\"Mfg_Area\" type=\"C\" " +
- "size=\"100\" isnull=\"true\" allow_multi_val=\"N\" />");
- ps.println("<attribute3 name=\"Product_Family\" type=\"C\" " +
- "size=\"100\" isnull=\"true\" allow_multi_val=\"N\" />");
- ps.println("<attributeWithText>This is test data</attributeWithText>");
- ps.print("</attributes>");
- ps.flush();
- ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
- // Document
- try {
- doc = builder.parse(bin);
- } catch (SAXException e) {
- e.printStackTrace();
- } catch (IOException e) {
- }
- // 1.
- Element rootElement = doc.getDocumentElement();
- printElement(rootElement);
- System.out.printf("</%s>",rootElement.getTagName());
- }
- static void printIndent() {
- for (int i = 0; i < indentLevel; ++i)
- System.out.print("\t");
- }
- static void printElement(Element element) {
- printIndent();
- System.out.printf("<%s",element.getTagName());
- // Attribute Map , AtrributeName 。
- //5. , Element
- NamedNodeMap nodeMap = element.getAttributes();
- for (int i = 0; i < nodeMap.getLength(); ++i) {
- Node node = nodeMap.item(i);
- if (i == 0)
- System.out.print(" ");
- //6. Name Value。
- System.out.printf("%s = %s ", node.getNodeName(), node.getNodeValue());
- if (i == nodeMap.getLength() - 1)
- System.out.print(" />");
- }
- String text = element.getTextContent();
- if (nodeMap.getLength() == 0)
- System.out.print(">");
- if (element != doc.getDocumentElement()) {
- if (!text.trim().isEmpty()) {
- System.out.print(text);
- System.out.printf("</%s>",element.getTagName());
- }
- }
- System.out.println();
- // 2.
- NodeList nodeList = element.getChildNodes();
- indentLevel++;
- for (int i = 0; i < nodeList.getLength(); ++i) {
- // 3.
- Node node = nodeList.item(i);
- // 4.
- if (node.getNodeType() == Node.ELEMENT_NODE) {
- printElement((Element) node);
- } else {
- printOtherNode(node);
- }
- }
- indentLevel--;
- }
- static void printOtherNode(Node node) {
- if (node.getNodeType() == Node.COMMENT_NODE) {
- printIndent();
- System.out.printf("<!--%s-->
",node.getNodeName());
- } else if (node.getNodeType() == Node.CDATA_SECTION_NODE) {
- printIndent();
- System.out.printf("<![CDATA[ %s ]]>
",node.getNodeName());
- }
- }
- private static Document doc;
- private static int indentLevel = 0;
- }
3. XMLのノードにアクセスするには、XPathを使用します. XPath言語の基本的な構文は次のとおりです. 1) /gridbag/row:ルート要素gridbagのサブ要素のすべてのrow要素を表します. 2) /gridbag/row[1]:[]を使用して、最初のサブエレメントを選択するエレメントのセットの特定のエレメントを選択します. 3) /gridbag/row[1]/cell[1]/@anchor:最初の行の最初のセルのanchorプロパティを説明します. 4) /gridbag/row/cell/@anchor:ルート要素gridbagのサブ要素である行要素のすべてのセルのanchorプロパティノードを記述します. 5) count(/gridbag/row):XPathはcountなどの有用な関数も提供します. Java SE 5にAPIを追加してXPath式を計算するには、XPathFactoryからXPathオブジェクトを作成する必要があります.たとえば、次のようにします. XPathFactory xpFactory = XPathFactory.newInstance(); XPath path = xpFactory.newXPath(); 次にevaluateメソッドを呼び出してXPath式を計算します.たとえば、次のようになります. String username = path.evaluate("/gridbag/row[1]/@anthor",doc); この形式のevaluate()メソッドは、文字列を返します.また、次のようなサブノードのセットを返します. NodeList nodes = path.evaluate("/gridbag/row",doc,XPathConstants.NODESET); ノードが1つしかない場合は、次のようにNODESETの代わりにNODE定数を使用できます. Node node = path.evaluate("/gridbag/row[1]",doc,XPathConstants.NODE); 結果が数値の場合は、次のようなXPathConstants.NUMBERを使用します. int count = ((Number)path.evaluate("count(/gridbag/row)",doc,XPathConstants.NUMBER)).intValue(); 次のコードは、XPathクエリXMLに基づいて一般的に使用されているコードのみをリストします.
- public class MyTest {
- // <projects>
- // <project id = "BP001">
- // <name>Banking Project</name>
- // <start-date>Jan 10 1999</start-date>
- // <end-date>Jan 10 2003</end-date>
- // </project>
- // <project id = "TP001">
- // <name>Telecommunication Project</name>
- // <start-date>March 20 1999</start-date>
- // <end-date>July 30 2004</end-date>
- // </project>
- // <project id = "PP001">
- // <name>Portal Project</name>
- // <start-date>Dec 10 1998</start-date>
- // <end-date>March 10 2006</end-date>
- // </project>
- // </projects>
- public static void main(String[] args) {
- XPathReader reader = new XPathReader("D:/Test.xml");
- // projects project id 。
- String expression = "/projects/project[1]/@id";
- System.out.println(reader.read(expression, XPathConstants.STRING));
- // projects project name
- expression = "/projects/project[2]/name";
- System.out.println(reader.read(expression, XPathConstants.STRING));
- // project , , name ,
- // name Telecommunication Project, name
- //project xpath , name 。
- expression = "//project[name=\"Telecommunication Project\"]/name";
- System.out.println(reader.read(expression, XPathConstants.STRING));
- // projects project
- expression = "/projects/project[3]";
- NodeList thirdProject = (NodeList) reader.read(expression, XPathConstants.NODESET);
- traverse(thirdProject);
- }
-
- private static void traverse(NodeList rootNode) {
- for (int index = 0; index < rootNode.getLength(); index++) {
- Node aNode = rootNode.item(index);
- if (aNode.getNodeType() == Node.ELEMENT_NODE) {
- NodeList childNodes = aNode.getChildNodes();
- if (childNodes.getLength() > 0) {
- System.out.println("Name:" + aNode.getNodeName() + ",Value:"
- + aNode.getTextContent());
- }
- traverse(aNode.getChildNodes());
- }
- }
- }
- }
-
- class XPathReader {
- private String xmlFile;
- private Document xmlDocument;
- private XPath xPath;
- public XPathReader(String xmlFile) {
- this.xmlFile = xmlFile;
- initObjects();
- }
- private void initObjects() {
- try {
- // XML DOM , 。
- xmlDocument = DocumentBuilderFactory.newInstance()
- .newDocumentBuilder().parse(xmlFile);
- // XPath
- xPath = XPathFactory.newInstance().newXPath();
- } catch (IOException ex) {
- } catch (SAXException ex) {
- } catch (ParserConfigurationException ex) {
- }
- }
- public Object read(String expression, QName returnType) {
- try {
- // , 。
- XPathExpression xPathExpression = xPath.compile(expression);
- //returnType evaluate 。
- return xPathExpression.evaluate(xmlDocument, returnType);
- } catch (XPathExpressionException ex) {
- return null;
- }
- }
- }
4. XMLのDOMモデルを構築し、DOMTreeModelをXMLファイルに出力します.
- public class MyTest {
- public static void main(String[] args) {
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- Element root = null, attr = null,subAttr = null;
- try {
- factory.setIgnoringElementContentWhitespace(true);
- DocumentBuilder db = factory.newDocumentBuilder();
- Document xmldoc = db.parse(new File("D:/Test.xml"));
- root = xmldoc.getDocumentElement();
- //1. DOMTreeModel
- // Element
- attr = xmldoc.createElement("attribute4");
- subAttr = xmldoc.createElement("subAttribute");
- // Element
- subAttr.setTextContent("Hello, I am sub-attribute.");
- attr.appendChild(subAttr);
- // Element
- attr.setAttribute("attrFirstName", "attrFirstValue");
- root.appendChild(attr);
- output(xmldoc, null);
- output(xmldoc, "D:/Test1_Edited.xml");
- // xpath 。
- attr = (Element)selectSingleNode("/attributes/attribute3",root);
- //
- attr.getAttributeNode("name").setNodeValue("Hello");
- output(attr,null);
- root.getElementsByTagName("attribute3").item(1).setTextContent("This is other test");
- output(root,null);
- //
- root.removeChild(root.getElementsByTagName("attributeWithText").item(0));
- output(root,null);
- // xpath ,
- NodeList attrs = selectNodes("/attributes/attribute3", root);
- for (int i = 0; i < attrs.getLength(); ++i)
- attrs.item(i).getParentNode().removeChild(attrs.item(i));
- root.normalize();
- output(root,null);
- } catch (ParserConfigurationException e) {
- } catch (SAXException e) {
- } catch (IOException e) {
- }
- }
-
- public static void output(Node node, String filename) {
- TransformerFactory transFactory = TransformerFactory.newInstance();
- try {
- Transformer transformer = transFactory.newTransformer();
- //
- transformer.setOutputProperty("encoding", "gb2312");
- transformer.setOutputProperty("indent", "yes");
- DOMSource source = new DOMSource();
- // DOM (holder)
- source.setNode(node);
- StreamResult result = new StreamResult();
- if (filename == null) {
- // transformer
- result.setOutputStream(System.out);
- } else {
- result.setOutputStream(new FileOutputStream(filename));
- }
- //
- transformer.transform(source, result);
- } catch (TransformerConfigurationException e) {
- } catch (TransformerException e) {
- } catch (FileNotFoundException e) {
- }
- }
-
- public static Node selectSingleNode(String express, Object source) {
- Node result = null;
- XPathFactory xpathFactory = XPathFactory.newInstance();
- XPath xpath = xpathFactory.newXPath();
- try {
- // xpath , compile 。
- result = (Node) xpath.evaluate(express, source, XPathConstants.NODE);
- } catch (XPathExpressionException e) {
- }
- return result;
- }
-
- public static NodeList selectNodes(String express, Object source) {82 NodeList result = null;
- XPathFactory xpathFactory = XPathFactory.newInstance();
- XPath xpath = xpathFactory.newXPath();
- try {
- result = (NodeList) xpath.evaluate(express, source, XPathConstants.NODESET);
- } catch (XPathExpressionException e) {
- }
- return result;
- }
- }