2010年2月13日土曜日

[java][dom]構造化されたタグの解除

こんな感じで。
---
/**
 * 子要素を親要素に移動して自身の要素を削除することによりタグを解除します。
 * @param doc
 * @param xpathExpression 削除したい要素を指定するためのXPath式
 */
public static void pullUpChildByXPath(final Document doc, final String xpathExpression) 
  throws XPathExpressionException{
  XPathFactory factory = XPathFactory.newInstance();
  XPath xpath = factory.newXPath();
  NodeList nodes = 
    (NodeList) xpath.evaluate(xpathExpression, doc, XPathConstants.NODESET);
  for(int i=0;i<nodes.getLength();i++){
    Node node = nodes.item(i);
    if(node.getNodeType() == Node.ELEMENT_NODE){
      pullUpChild((Element)node);
    }
  }
}
/**
 * 子要素を親要素に移動して自身の要素を削除します。
 * @param element 削除したい要素
 */
public static void pullUpChild(final Element element){
  //親を呼び出します。
  Node parent = element.getParentNode();
  NodeList childNodes = element.getChildNodes();  
  //ノードの挿入は親に頼みます。
  for(int j=0; j < childNodes.getLength(); j++){
    Node child = childNodes.item(j).cloneNode(true);
    parent.insertBefore(child, element);
  }
  parent.removeChild(element);
}
---

テストケースです。
---
@Test
public void testPullUpChildByXPath_DocBook4_OrderedList() throws Exception{
  StringBuilder sb = new StringBuilder();
  sb.append("<section>");
  sb.append("<title>Java Platform, Standard Edition 6 API</title>");
  sb.append("<orderedlist>");
  sb.append("<title>パッケージ</title>");
  sb.append("<listitem>");
  sb.append("<para revisionflag=\"added\">java.applet</para>");
  sb.append("</listitem>");
  sb.append("<listitem>");
  sb.append("<para>java.<phrase revisionflag=\"changed\">awt</phrase></para>");
  sb.append("</listitem>");
  sb.append("<listitem>");
  sb.append("<para>java.beans</para>");
  sb.append("<para>Beans (JavaBeans アーキテクチャーに基づいたコンポーネント) の開発に関連するクラスが含まれています。</para>");
  sb.append("</listitem>");
  sb.append("</orderedlist>");
  sb.append("</section>");
  String xml = sb.toString();
  
  sb.setLength(0);
  sb.append("<section>");
  sb.append("<title>Java Platform, Standard Edition 6 API</title>");
  sb.append("<title>パッケージ</title>");
  sb.append("<para revisionflag=\"added\">java.applet</para>");
  sb.append("<para>java.<phrase revisionflag=\"changed\">awt</phrase></para>");
  sb.append("<para>java.beans</para>");
  sb.append("<para>Beans (JavaBeans アーキテクチャーに基づいたコンポーネント) の開発に関連するクラスが含まれています。</para>");
  sb.append("</section>");
  String expected = sb.toString();
  
  Document doc = DomUtils.stringToDocument(xml);
  //子の引き上げは下層からやります。
  DomUtils.pullUpChildByXPath(doc, "/section/orderedlist/listitem");
  DomUtils.pullUpChildByXPath(doc, "/section/orderedlist");
  String actual = DomUtils.nodeToString(doc);
  actual = XMLUtils.removeXMLDeclaration(actual);
  assertEquals(expected, actual);
}
---

ではまた。

0 件のコメント:

コメントを投稿