4 * License : The MIT License
5 * Copyright(c) 2010 MikuToga Partners
8 package jp.sfjp.mikutoga.xml;
10 import java.util.Iterator;
11 import java.util.LinkedList;
12 import java.util.List;
13 import java.util.NoSuchElementException;
14 import org.w3c.dom.Element;
15 import org.w3c.dom.Node;
20 public final class DomUtils {
23 private static final char BS_CHAR = (char) 0x005c;
31 throw new AssertionError();
35 * 要素からxsd:string型属性値を読み取る。
39 * @throws TogaXmlException 属性値が見つからなかった。
41 public static String getStringAttr(Element elem, String attrName)
42 throws TogaXmlException{
43 if( ! elem.hasAttribute(attrName) ){
44 String message = "Attr:[" + attrName + "] "
46 + "Elem:[" + elem.getTagName()+"]";
47 throw new TogaXmlException(message);
52 result = elem.getAttribute(attrName);
53 }catch(IllegalArgumentException e){
54 String message = "Invalid attribute form [" + attrName + "]";
55 throw new TogaXmlException(message, e);
62 * 要素からxsd:boolean型属性値を読み取る。
66 * @throws TogaXmlException 属性値が見つからなかった。
68 public static boolean getBooleanAttr(Element elem, String attrName)
69 throws TogaXmlException{
70 String value = getStringAttr(elem, attrName);
74 result = DatatypeIo.parseBoolean(value);
75 }catch(IllegalArgumentException e){
77 "Invalid boolean attribute form "
78 + "[" + attrName + "][" + value + "]";
79 throw new TogaXmlException(message, e);
86 * 要素からxsd:integer型属性値を読み取る。
90 * @throws TogaXmlException 属性値が見つからなかった。
92 public static int getIntegerAttr(Element elem, String attrName)
93 throws TogaXmlException{
94 String value = getStringAttr(elem, attrName);
98 result = DatatypeIo.parseInt(value);
99 }catch(IllegalArgumentException e){
101 "Invalid integer attribute form "
102 + "[" + attrName + "][" + value + "]";
103 throw new TogaXmlException(message, e);
110 * 要素からxsd:float型属性値を読み取る。
112 * @param attrName 属性名
114 * @throws TogaXmlException 属性値が見つからなかった。
116 public static float getFloatAttr(Element elem, String attrName)
117 throws TogaXmlException{
118 String value = getStringAttr(elem, attrName);
122 result = DatatypeIo.parseFloat(value);
123 }catch(IllegalArgumentException e){
125 "Invalid float attribute form "
126 + "[" + attrName + "][" + value + "]";
127 throw new TogaXmlException(message, e);
134 * 要素から日本語Windows用ファイル名を属性値として読み取る。
135 * 念のため文字U+00A5は文字U-005Cに変換される。
137 * @param attrName 属性名
139 * @throws TogaXmlException 属性値が見つからなかった。
141 public static String getSjisFileNameAttr(Element elem, String attrName)
142 throws TogaXmlException{
145 result = getStringAttr(elem, attrName);
146 }catch(IllegalArgumentException e){
148 "Invalid winfile attribute form "
149 + "[" + attrName + "]";
150 throw new TogaXmlException(message, e);
153 result = result.replace("" + '\u00a5', "" + BS_CHAR);
159 * 指定された名前の子要素を1つだけ返す。
161 * @param tagName 子要素名
163 * @throws TogaXmlException 1つも見つからなかった
165 public static Element getChild(Element parent, String tagName)
166 throws TogaXmlException{
167 Element result = null;
169 for(Node node = parent.getFirstChild();
171 node = node.getNextSibling() ){
173 if(node.getNodeType() != Node.ELEMENT_NODE) continue;
174 Element elem = (Element) node;
176 String elemTagName = elem.getTagName();
177 if( tagName.equals(elemTagName) ){
185 "Elem:[" + tagName + "] was not found in "
186 +"Elem:[" + parent.getTagName() + "]";
187 throw new TogaXmlException(message);
194 * 親要素が指定された名前の子要素を持つか判定する。
196 * @param tagName 子要素名
197 * @return 指定名の子要素が存在すればtrue
199 public static boolean hasChild(Element parent, String tagName){
200 for(Node node = parent.getFirstChild();
202 node = node.getNextSibling() ){
204 if(node.getNodeType() != Node.ELEMENT_NODE) continue;
205 Element elem = (Element) node;
207 String elemTagName = elem.getTagName();
208 if( tagName.equals(elemTagName) ) return true;
215 * 指定された名前の子要素のリストを返す。
217 * @param childTag 子要素名
220 public static List<Element> getChildList(Element parent,
222 List<Element> result = new LinkedList<Element>();
224 for(Node node = parent.getFirstChild();
226 node = node.getNextSibling() ){
228 if(node.getNodeType() != Node.ELEMENT_NODE) continue;
229 Element elem = (Element) node;
231 String tagName = elem.getTagName();
232 if( ! childTag.equals(tagName) ) continue;
241 * 指定された名前の子要素の列挙子を返す。
243 * @param childTag 子要素名
246 public static Iterator<Element> getChildIterator(Element parent,
250 firstElem = getChild(parent, childTag);
251 }catch(TogaXmlException e){
255 Iterator<Element> result = new ElemIterator(firstElem);
261 * 指定された名前の子要素のforeachを返す。
263 * @param childTag 子要素名
264 * @return 子要素のforeach
266 public static Iterable<Element> getEachChild(Element parent,
268 final Iterator<Element> iterator = getChildIterator(parent, childTag);
269 Iterable<Element> result = new Iterable<Element>(){
271 public Iterator<Element> iterator(){
281 * @return 次の要素。なければnull
283 public static Element nextElement(Element elem){
284 Node nextNode = elem;
286 nextNode = nextNode.getNextSibling();
287 if(nextNode == null) break;
288 if(nextNode.getNodeType() == Node.ELEMENT_NODE){
293 return (Element) nextNode;
299 * @return 次の要素。なければnull
301 public static Element nextNamedElement(Element elem){
302 String tagName = elem.getTagName();
303 Element nextElem = elem;
305 nextElem = nextElement(nextElem);
306 if(nextElem == null) break;
307 if(tagName.equals(nextElem.getTagName())) break;
314 * 同じ親要素と同じ要素名を持つ兄弟要素を列挙する列挙子。
316 private static final class ElemIterator implements Iterator<Element> {
317 private Element next;
321 * @param elem 最初の要素。nullを指定すれば空列挙子となる。
323 ElemIterator(Element elem){
330 * @return {@inheritDoc}
333 public boolean hasNext(){
334 if(this.next == null) return false;
340 * @return {@inheritDoc}
341 * @throws NoSuchElementException {@inheritDoc}
344 public Element next() throws NoSuchElementException{
345 if(this.next == null) throw new NoSuchElementException();
346 Element result = this.next;
347 this.next = nextNamedElement(this.next);
356 public void remove(){
357 throw new UnsupportedOperationException();