/* * $Id: GLSDDocumentModuleChecker.cpp,v 1.8 2006/06/27 13:11:40 ozawa Exp $ * * Copyright 2005- ONGS Inc. All rights reserved. * * author: Masanori OZAWA (ozawa@ongs.co.jp) * version: $Revision: 1.8 $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the ONGS Inc. * */ #include "xdtp.h" #include "modules/GLSDDocumentModuleChecker.h" #include "XMLTool.h" using namespace XDTP; GLSDDocumentModuleChecker::GLSDDocumentModuleChecker() { } GLSDDocumentModuleChecker::~GLSDDocumentModuleChecker() { } /** * 文書モジュールの正当性をチェックします。 * * @param aDocument ロードした直後のXMLファイル * @return 変換処理を中断する場合は false を戻します。 */ bool GLSDDocumentModuleChecker::checkFormat(xmlDocPtr aDocument) { bool result = true; int count = 0; int count2 = 0; int count3 = 0; XMLTool tool; xmlNodePtr node; xmlNodePtr child; xmlNodePtr root = xmlDocGetRootElement(aDocument); xmlXPathObjectPtr obj; xmlXPathObjectPtr children; xmlXPathObjectPtr tmpobj; xmlXPathObjectPtr tmpobj2; xmlNodeSetPtr nodes; xmlNodeSetPtr childset; xmlNodeSetPtr tmpobjset; // alias のチェック if (!checkAlias(root)) { return false; } // import のチェック obj = tool.getNodeList(root, "//import"); if (obj) { nodes = obj->nodesetval; for (count = 0; result && count < nodes->nodeNr; count++) { if (!tool.isElement(nodes->nodeTab[count])) continue; if (!xmlHasProp(nodes->nodeTab[count], (const xmlChar*)"type") || !xmlHasProp(nodes->nodeTab[count], (const xmlChar*)"ref")) { result = false; } } xmlXPathFreeObject(obj); if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad import." LINE_SEP, APP_NAME); } // mark のチェック obj = (result ? tool.getNodeList(root, "//mark") : NULL); if (obj) { nodes = obj->nodesetval; for (count = 0; result && count < nodes->nodeNr; count++) { if (!tool.isElement(nodes->nodeTab[count])) continue; if (!xmlHasProp(nodes->nodeTab[count], (const xmlChar*)"type")) { result = false; } } xmlXPathFreeObject(obj); if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad mark." LINE_SEP, APP_NAME); } // list のチェック obj = (result ? tool.getNodeList(root, "//list") : NULL); if (obj) { nodes = obj->nodesetval; for (count = 0; result && count < nodes->nodeNr; count++) { node = nodes->nodeTab[count]; if (!tool.isElement(node)) continue; result = checkFormat_list(node); } xmlXPathFreeObject(obj); if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad list." LINE_SEP, APP_NAME); } // thebibliography のチェック obj = (result ? tool.getNodeList(root, "//thebibliography") : NULL); if (obj) { nodes = obj->nodesetval; for (count = 0; result && count < nodes->nodeNr; count++) { node = nodes->nodeTab[count]; if (!tool.isElement(node)) continue; children = tool.getNodeList(node, "./bibitem"); if (!children) { result = false; } else { childset = children->nodesetval; if (1 > childset->nodeNr) result = false; for (count2 = 0; result && count2 < childset->nodeNr; count2++) { child = childset->nodeTab[count2]; tmpobj = tool.getNodeList(child, "./title"); if (!tmpobj) result = false; else { if (0 >= tmpobj->nodesetval->nodeNr) result = false; xmlXPathFreeObject(tmpobj); } tmpobj = tool.getNodeList(child, "./publisher"); if (tmpobj) { if (1 < tmpobj->nodesetval->nodeNr) result = false; xmlXPathFreeObject(tmpobj); } tmpobj = tool.getNodeList(child, "author | title | publisher | year"); if (tmpobj) { tmpobjset = tmpobj->nodesetval; for (count3 = 0; result && count3 < tmpobjset->nodeNr; count3++) { tmpobj2 = tool.getNodeList(tmpobjset->nodeTab[count3], "./p"); if (!tmpobj2) result = false; else { if (1 != tmpobj2->nodesetval->nodeNr) result = false; xmlXPathFreeObject(tmpobj2); } } xmlXPathFreeObject(tmpobj); } } xmlXPathFreeObject(children); } } xmlXPathFreeObject(obj); if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad thebibliography." LINE_SEP, APP_NAME); } // footnote のチェック obj = (result ? tool.getNodeList(root, "//footnote") : NULL); if (obj) { nodes = obj->nodesetval; for (count = 0; count < nodes->nodeNr; count++) { if (!tool.isElement(nodes->nodeTab[count])) continue; children = tool.getNodeList(nodes->nodeTab[count], "./*"); if (children) { if (0 != children->nodesetval->nodeNr) result = false; xmlXPathFreeObject(children); } } xmlXPathFreeObject(obj); if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad footnote." LINE_SEP, APP_NAME); } // access のチェック obj = (result ? tool.getNodeList(root, "//access") : NULL); if (obj) { nodes = obj->nodesetval; for (count = 0; result && count < nodes->nodeNr; count++) { node = nodes->nodeTab[count]; if (!tool.isElement(node)) continue; if (!xmlHasProp(node, (const xmlChar*)"ref")) { result = false; } children = (result ? tool.getNodeList(node, "./*") : NULL); if (children) { if (0 != children->nodesetval->nodeNr) result = false; xmlXPathFreeObject(children); } } xmlXPathFreeObject(obj); if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad access." LINE_SEP, APP_NAME); } // ruby のチェック obj = (result ? tool.getNodeList(root, "//ruby") : NULL); if (obj) { nodes = obj->nodesetval; for (count = 0; result && count < nodes->nodeNr; count++) { node = nodes->nodeTab[count]; if (!tool.isElement(node)) continue; if (!xmlHasProp(node, (const xmlChar*)"rubytext")) { result = false; } children = tool.getNodeList(node, "./*"); if (children) { if (0 != children->nodesetval->nodeNr) result = false; xmlXPathFreeObject(children); } } xmlXPathFreeObject(obj); if (!result) fprintf(stderr, "%s: GLSDDocumentModuleChecker: bad ruby." LINE_SEP, APP_NAME); } return result; } /** * aliasエレメントの確認。 * * @param aDocumentRoot * XMLのルートノード */ bool GLSDDocumentModuleChecker::checkAlias(xmlNodePtr aDocumentRoot) { bool result = true; int count; XMLTool tool; xmlNodePtr node; xmlNodePtr child; xmlNodeSetPtr nodes; xmlXPathObjectPtr obj = tool.getNodeList(aDocumentRoot, "//alias"); if (obj) { nodes = obj->nodesetval; for (count = 0; result && count < nodes->nodeNr; count++) { node = nodes->nodeTab[count]; if (!node->parent || xmlStrcmp(node->parent->name, (xmlChar*)"p") != 0) result = false; else { for (child = node->children; result && child; child = child->next) { if (!tool.isText(child)) result = false; } if (result) { if (0 >= tool.getText(node).length()) result = false; } } } xmlXPathFreeObject(obj); } return result; } /** * list要素の構造をチェックします。 * * @param aNode 親list要素 * @return 変換処理を中断する場合は false を戻します。 */ bool GLSDDocumentModuleChecker::checkFormat_list(xmlNodePtr aNode) { bool result = true; int count, count2; XMLTool tool; xmlNodePtr node; xmlNodePtr child; xmlXPathObjectPtr children; xmlXPathObjectPtr tmpobj; xmlNodeSetPtr childset; xmlNodeSetPtr tmpobjset; children = tool.getNodeList(aNode, "./item"); if (children) { childset = children->nodesetval; for (count = 0; result && count < childset->nodeNr; count++) { child = childset->nodeTab[count]; // 最低1つのp要素が必要 tmpobj = tool.getNodeList(child, "./p"); if (!tmpobj) result = false; else { if (0 >= tmpobj->nodesetval->nodeNr) result = false; xmlXPathFreeObject(tmpobj); } // ネストされたlist要素をチェック tmpobj = tool.getNodeList(child, "./list"); if (tmpobj) { tmpobjset = tmpobj->nodesetval; for (count2 = 0; result && count2 < tmpobjset->nodeNr; count2++) { node = tmpobjset->nodeTab[count2]; if (!tool.isElement(node)) continue; result = checkFormat_list(node); } xmlXPathFreeObject(tmpobj); } } xmlXPathFreeObject(children); } return result; }