728x90
상대 경로 탐색


	
		JFC/Swing
		
			
				JTree
				
					
						JTree - 트리 구조
						com.cafe24.twilightsh.gui.jfc.Round23Ex04
					
					
						JTree - 하위 노드
						com.cafe24.twilightsh.gui.jfc.Round23Ex05
					
					
						JTree - Style
						com.cafe24.twilightsh.gui.jfc.Round23Ex06
					
				
			
			
				JTable
				
					
						JTable - 표
						com.cafe24.twilightsh.gui.jfc.Round23Ex08
					
					
						JTable - 표 제어
						com.cafe24.twilightsh.gui.jfc.Round23Ex09
					
				
			
		
	

	
		AWT
	


index.xml
xpath-relative.png

index.xml의 내용을 읽어 tree로 표현한 화면.

index.xml 파일은 트리 구조로 내용물을 구성하고, 이를 읽어 JTree로 표현하고자 했습니다.

핵심은 복수의 ring 요소를 품은 rings 요소는, 다시 rings 요소를 가질 수 있다는 점입니다. 즉, ring 요소는 자식으로 복수의 ring을 가질 수 있습니다. 또한 이는 계속해서 반복될 수도 있습니다.

그래서 ring은 buildRingList라는 메서드를 호출해서 구성토록 하고, 만약 이 ring이 또다시 ring들을 가지고 있다면, 이 각각의 ring들마다 buildRingList 메서드를 호출해서 구성하도록 하면 간단하게 구현할 수 있을 것 같았습니다. 반복작업도 줄이고, 몇 단계로 깊게 ring들이 중첩되어 가지고 있어도 buildRingList 메서드가 알아서 처리해주도록 말이죠.

문제는 그러려면 ring마다 단위로 끊어서 인식하고, 해당 범위 내의 처리만 하고, 그 이하는 또다시 그 범위 내에서만 처리하도록 할 필요가 있었습니다.(간단한 기능인데 말로 설명하기가 힘드네요...)

그런데 제가 가지고 있는 XPath 표현식 정보 중에는 루트부터의 절대경로나 전체에서 탐색하기 등은 나와도, 상대 경로 정보는 나와있질 않더군요. 그래서 상대 경로 탐색법을 찾아봤습니다. 생각보다 잘 안 나오긴 했지만, 그래도 결국 찾아내어 완성했습니다.

		DefaultMutableTreeNode mutableNodeTop = new DefaultMutableTreeNode(
				"TOP");

		XmlHelper xmlHelper = new XmlHelper();
		Document indexXml = xmlHelper.read(new File(
				"resource/com/cafe24/twilightsh/jfc/index.xml"));
		try {
			NodeList ringList = (NodeList) xpath.evaluate("./rings/ring",
					indexXml, XPathConstants.NODESET);
			if (ringList != null) {
				this.buildRingList(mutableNodeTop, ringList);
			}
		} catch (XPathExpressionException e) {
			throw new RuntimeException("!XML!", e);
		}

		DefaultTreeModel treeModel = new DefaultTreeModel(mutableNodeTop);

		final JTree tree = new JTree(treeModel);
첫번째 바로 자식 노드들로 목록을 만들어 buildRingList 메서드를 호출했습니다.
	/**
	 * @param parentTree
	 *            ring을 붙일 트리.
	 * @param ringList
	 *            ring 목록
	 * @throws XPathExpressionException
	 */
	private void buildRingList(final DefaultMutableTreeNode parentTree,
			final NodeList ringList) throws XPathExpressionException {
		for (int i = 0; i < ringList.getLength(); i++) {
			Node ring = ringList.item(i);
			Node ringTitle = (Node) xpath.evaluate("./title", ring,
					XPathConstants.NODE);
			DefaultMutableTreeNode ringTree = new DefaultMutableTreeNode(
					ringTitle.getTextContent());
			parentTree.add(ringTree);

			NodeList practiceList = (NodeList) xpath.evaluate(
					"./Practices/Practice", ring, XPathConstants.NODESET);
			if (practiceList != null) {
				this.buildPracticeList(ringTree, practiceList);
			}

			NodeList childRingList = (NodeList) xpath.evaluate("./rings/ring",
					ring, XPathConstants.NODESET);
			if (childRingList != null) {
				this.buildRingList(ringTree, childRingList);
			}
		}
	}

Index.java 해당 코드가 든 파일을 첨부합니다...만, 불필요한 파일은 첨부하지 않았기에 오류가 날 수 있습니다. 그런 파일들은 적당히 껍데기만 만드시면 됩니다.

buildRingList 메서드는 ring 노드를 하나씩 내용물을 트리 노드를 구성하고 부모 트리에 붙입니다. 그리고, 해당 ring 노드가 자식으로 ring 노드들을 가지고 있으면, 그 노드 목록을 가져와 또다시 buildRingList 메서드를 호출합니다.

여기서 중요한 점은 XPath 표현식에서 현재 노드를 나타내는 것은 ‘.’이라는 점입니다. 현재 노드의 부모 노드는 ‘..’입니다. 웹페이지에서의 상대 경로나, 리눅스, 도스 등에서 상대 경로를 나타낼 때 사용하는 것과 똑같습니다.

*찾아낸 자료 링크
XPath 이야기 (http://www.nextree.co.kr/p6278/ ) : ‘마. XPath의 문법’ 참조
반응형

+ Recent posts