Skip to content

Instantly share code, notes, and snippets.

@kiarina
Created May 15, 2015 01:00
Show Gist options
  • Save kiarina/5ca9f932b2bbf5febbc6 to your computer and use it in GitHub Desktop.
Save kiarina/5ca9f932b2bbf5febbc6 to your computer and use it in GitHub Desktop.
for parse xml
<?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