Created
May 15, 2015 01:00
-
-
Save kiarina/5ca9f932b2bbf5febbc6 to your computer and use it in GitHub Desktop.
for parse xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?PHP | |
#-------------------------------------------------- | |
# Main | |
#-------------------------------------------------- | |
if ($argc < 1) { | |
exit(); | |
} | |
$sspjPath = $argv[1]; | |
if (is_file($sspjPath) == false) { | |
echo "sspj file is not exist. ${sspjPath}" . PHP_EOL; | |
exit(1); | |
} | |
$targets = array( | |
array('name' => 'motion', 'xmlElements' => array(), 'retriever' => 'retrieveSSAEMotion'), | |
array('name' => 'collision', 'xmlElements' => array(), 'retriever' => 'retrieveSSAECollision'), | |
); | |
// 分割したXMLElementを生成 | |
foreach ($targets as $key => &$target) { | |
$target['xmlElements']['sspj'] = createSSPJXMLElement($sspjPath, $target['name']); | |
$target['xmlElements']['ssae'] = createSSAEXMLElement($sspjPath, $target['retriever']); | |
} | |
unset($target); | |
// 元ファイルをバックアップ | |
backupSSPJFile($sspjPath); | |
// XMLファイルを出力 | |
foreach ($targets as $target) { | |
$dir = dirname($sspjPath); | |
$basename = basename($sspjPath, ".sspj"); | |
foreach ($target['xmlElements'] as $suffix => $xmlElement) { | |
outputXML($xmlElement, sprintf("%s/%s_%s.%s", $dir, $basename, $target['name'], $suffix)); | |
} | |
} | |
#-------------------------------------------------- | |
# Common | |
#-------------------------------------------------- | |
function loadXML($xmlPath) { | |
$xmlElement = @simplexml_load_file($xmlPath); | |
if ($xmlElement == false) { | |
echo "can not open xml file."; | |
exit(1); | |
} | |
return $xmlElement; | |
} | |
function outputXML($xmlElement, $filename) { | |
$fp = fopen($filename, 'wt'); | |
if ($fp === false) { | |
echo "file can not open. ${filename}" . PHP_EOL; | |
exit(1); | |
} | |
fputs($fp, $xmlElement->asXML()); | |
fclose($fp); | |
} | |
function backupSSPJFile($sspjPath) { | |
$dir = dirname($sspjPath); | |
$basename = basename($sspjPath, ".sspj"); | |
$backupPath = sprintf("%s/%s.sspj.backup", $dir, $basename); | |
rename($sspjPath, $backupPath); | |
} | |
#-------------------------------------------------- | |
# SSPJ | |
#-------------------------------------------------- | |
function createSSPJXMLElement($sspjPath, $targetName) { | |
// 基本情報 | |
$dir = dirname($sspjPath); | |
$basename = basename($sspjPath, ".sspj"); | |
// XML解析 | |
$xmlElement = loadXML($sspjPath); | |
// ssae名の変更 | |
$animepackName = sprintf("%s_%s.ssae", $basename, $targetName); | |
$xmlElement = setSSPJAnimepackName($xmlElement, $animepackName); | |
return $xmlElement; | |
} | |
function setSSPJAnimepackName($xmlElement, $animepackName) { | |
if ($xmlElement->animepackNames->value->count() != 1) { | |
echo "illegal sspj data." . PHP_EOL; | |
exit(1); | |
} | |
$xmlElement->animepackNames->value[0] = $animepackName; | |
return $xmlElement; | |
} | |
#-------------------------------------------------- | |
# SSAE | |
#-------------------------------------------------- | |
function createSSAEXMLElement($sspjPath, $retriever) { | |
// 基本情報 | |
$dir = dirname($sspjPath); | |
$basename = basename($sspjPath, ".sspj"); | |
$ssaePath = sprintf("%s/%s.ssae", $dir, $basename); | |
// XML解析 | |
$xmlElement = loadXML($ssaePath); | |
// データ更新 | |
$targetXMLElement = $retriever($xmlElement); | |
return $xmlElement; | |
} | |
function retrieveSSAEMotion($baseXMLElement) { | |
$xmlElement = new SimpleXMLElement($baseXMLElement->asXML()); | |
// judgement* パーツを削除 | |
$xmlElement = deleteSSAEPartListValue($xmlElement, function($value) { | |
return strpos((string)$value->name, 'judgement') !== false; | |
}); | |
// judgement* パーツのアニメ情報を削除する | |
$xmlElement = deleteSSAEPartAnime($xmlElement, function($partAnime) { | |
return strpos((string)$partAnime->partName, 'judgement') !== false; | |
}); | |
return $xmlElement; | |
} | |
function retrieveSSAECollision($baseXMLElement) { | |
$xmlElement = new SimpleXMLElement($baseXMLElement->asXML()); | |
$partNamesHavingUserData = getSSAEPartNamesHavingUserData($xmlElement); | |
// root, judgement* 以外のパーツを削除 | |
$xmlElement = deleteSSAEPartListValue($xmlElement, function($value) use ($partNamesHavingUserData) { | |
if (strpos((string)$value->name, 'judgement') !== false || strpos((string)$value->name, 'root') !== false) { | |
return false; | |
} else if (in_array((string)$value->name, $partNamesHavingUserData)) { | |
return false; | |
} else { | |
return true; | |
} | |
}); | |
// root, judgement* 以外のパーツのアニメ情報を削除する | |
$xmlElement = deleteSSAEPartAnime($xmlElement, function($partAnime) use ($partNamesHavingUserData) { | |
if (strpos((string)$partAnime->partName, 'root') !== false || strpos((string)$partAnime->partName, 'judgement') !== false) { | |
return false; | |
} else if (in_array((string)$partAnime->partName, $partNamesHavingUserData)) { | |
return false; | |
} else { | |
return true; | |
} | |
}); | |
return $xmlElement; | |
} | |
function deleteSSAEPartListValue($xmlElement, $isDeleteFunc) { | |
// 親情報を収拾 | |
$parentInfo = array( | |
/* | |
$arrayIndex => $name, | |
*/ | |
); | |
for ($i = 0; $i < $xmlElement->Model->partList->value->count(); $i++) { | |
$value = $xmlElement->Model->partList->value[$i]; | |
$parentInfo[(int)$value->arrayIndex] = (string)$value->name; | |
} | |
// root, judgement* 以外を削除 | |
$deleteList = array(); | |
for ($i = 0; $i < $xmlElement->Model->partList->value->count(); $i++) { | |
$value = $xmlElement->Model->partList->value[$i]; | |
if ($isDeleteFunc($value)) { | |
$deleteList[] = $i; | |
} | |
} | |
rsort($deleteList); | |
foreach ($deleteList as $i) { | |
unset($xmlElement->Model->partList->value[$i]); | |
} | |
// arrayIndexを付け直す | |
$newParentInfo = array( | |
/* | |
$name => $arrayIndex, | |
*/ | |
); | |
for ($i = 0; $i < $xmlElement->Model->partList->value->count(); $i++) { | |
$value = $xmlElement->Model->partList->value[$i]; | |
$value->arrayIndex = $i; | |
$newParentInfo[(string)$value->name] = $i; | |
} | |
// parentIndexを付け直す | |
for ($i = 0; $i < $xmlElement->Model->partList->value->count(); $i++) { | |
$value = $xmlElement->Model->partList->value[$i]; | |
if ((int)$value->parentIndex != -1) { | |
$value->parentIndex = $newParentInfo[$parentInfo[(int)$value->parentIndex]]; | |
} | |
} | |
return $xmlElement; | |
} | |
function deleteSSAEPartAnime($xmlElement, $isDeleteFunc) { | |
for ($i = 0; $i < $xmlElement->animeList->anime->count(); $i++) { | |
for ($j = $xmlElement->animeList->anime[$i]->partAnimes->partAnime->count() - 1; $j >= 0; $j--) { | |
$partAnime = $xmlElement->animeList->anime[$i]->partAnimes->partAnime[$j]; | |
if ($isDeleteFunc($partAnime)) { | |
unset($xmlElement->animeList->anime[$i]->partAnimes->partAnime[$j]); | |
} | |
} | |
} | |
return $xmlElement; | |
} | |
function getSSAEPartNamesHavingUserData($xmlElement) { | |
$partNames = array( | |
/* | |
$partName => $count, | |
*/ | |
); | |
for ($i = 0; $i < $xmlElement->animeList->anime->count(); $i++) { | |
$anime = $xmlElement->animeList->anime[$i]; | |
for ($j = 0; $j < $anime->partAnimes->partAnime->count(); $j++) { | |
$partAnime = $anime->partAnimes->partAnime[$j]; | |
for ($k = 0; $k < $partAnime->attributes->attribute->count(); $k++) { | |
$attribute = $partAnime->attributes->attribute[$k]; | |
if ((string)$attribute['tag'] == 'USER') { | |
@$partNames[(string)$partAnime->partName]++; | |
} | |
} | |
} | |
} | |
$partNames = array_keys($partNames); | |
return $partNames; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment