2014-01-19 3 views
0

나는 중첩 된 XML을 사용하여 노드뿐만 아니라 각각 다른 속성 키와 값을 가져와야합니다.PHP는 고유 한 속성을 가진 nexted XML을 구문 분석합니다.

PHP에서 재귀 함수를 작성하여 필자가 찾고있는 함수를 작성하려고했습니다. 내 XML은 다음과 같습니다 ...

<document> 
<character> 
    <literal>name</literal> 
    <codepoint> 
     <cp_value cp_type="ucs">4e9c</cp_value> 
     <cp_value cp_type="jis208">16-01</cp_value> 
    </codepoint> 
    <radical> 
     <rad_value rad_type="classical">7</rad_value> 
     <rad_value rad_type="nelson_c">1</rad_value> 
    </radical> 
      <meaning_group> 
       <meaning>this</meaning> 
       <meaning>that</meaning> 
      </meaning_group> 
    </character> 
    ... 
</document> 

문제는 모든 [문자] 노드가 똑같은 자식을 가지고있는 것은 아닙니다.

속성 키와 값을 결합하여 하나의 키로 결합하려고 시도하고 그 값을 값으로 연결하려고합니다. 속성이 없으면 태그 이름을 키로 사용하려고합니다. 또한 일부 어린이는 특성이없는 동일한 이름을가집니다. 이 경우에는 줄 바꿈으로 구분 된 한 필드에 넣기 만하면됩니다. 감사!!

I 출력하고자 배열의
["literal"] => "name", 
["cp_type-ucs"] => "4e9c", 
["cp_type-jis208"] => "16-01", 
["rad_type-classical"] => "7", 
["rad_type-nelson_c"] => "1", 
["meaning"] => "this\nthat" 

...

모든 모든 도움을 주시면 감사하겠습니다! 감사!

편집 : 레이어를 통과하여 에코하기 위해 태그 이름을 가져 오는 데 사용할 수있는 몇 가지 코드가 추가되었지만 어떤 이유로 든 배열을 채울 수 없습니다. "문자"태그 만 배열에 들어갑니다.

function ripXML($file) { 
    $xml = simplexml_load_file ($file); 
    return (peelTags ($xml , array())); 
} 
function peelTags($node, $tag) { 
// find if there are children. (IF SO, there shouldn't be 
$numChildren = @count ($node->children()); 

if ($numChildren != 0) { 
    foreach ($node->children() as $child) { 
     $tag [] = $child->getName(); 
     peelTags ($child, $tag); 

     echo "<br />Name = " . $child->getName(); 
    } 
} 
    return $tag; 
} 

$file = "dictionarytest.xml"; 
print_r (ripXML ($file)); 

EDIT 2 - 마지막으로 알아 냈습니다. 조금 어수선하고 최선의 방법은 아니지만 내가 직면 한 문제를 해결했습니다. 다른 누군가가 비슷한 것을 필요로하는 경우에는 여기에 있습니다!

$_SESSION ["a"] = array(); 
$_SESSION ["c"] = 0; 
function ripXML($file) { 
$xml = simplexml_load_file ($file); 
return (peelTags ($xml, array())); 
} 
function peelTags($node, $tag) { 
// find if there are children. (IF SO, there shouldn't be 
$numChildren = @count ($node->children()); 

if ($numChildren != 0) { 
    foreach ($node->children() as $child) { 
     peelTags ($child, $tag); 
     $tag = $child->getName(); 
     if ($tag == "literal") { 
      $_SESSION ["c"] ++; 
     } 
     $value = trim($child->__toString()); 
     if (isset ($value) && $value != "") { 
      if ($child->attributes()) { 
       foreach ($child->attributes() as $k => $v) { 
        if (isset ($v) && $v != "") { 
         $_SESSION ["a"] [$_SESSION ["c"]] [$k . "_" . $v] = $value; 
        } 
       } 
      } else { 
       $_SESSION ["a"] [$_SESSION ["c"]] [$tag] = $value; 
      } 
     } 
    } 
} 
return 1; 
} 

$file = "dictionarytest.xml"; 
print_r (ripXML ($file)); 
print_r ($_SESSION ["a"]); 

글로벌 세션 변수를 사용하여 재귀 알고리즘의 배열과 카운터를 저장했습니다. 누구에게 더 좋은 제안이 있는지 나는 모른다. 가능한 경우이 기능을 최적화하고 싶습니다. 난 단지 5 항목의 XML 파일에서 그것을 테스트했지만, 내 실제 파일은 4000 이상이됩니다.

+0

http://php.net/dom 그 –

+0

당신이 시도 코드를 제시해주십시오 배우고 그것을 작동 밤은 왜. 당신이 원하는 것은 가능합니다. –

+0

속성 및 값이 특정 순서로 필요합니까? – blissini

답변

1

... 혼란스러워. 내가하지 구문 검사를 한 또는이를 테스트,하지만 난 같은 그 무언가를 생각 ..

$domd=new DOMDocument(); 
$domd->loadXML($xml); 
$interestingdomnode=$domd->getElementsByTagName("character")->item(0); 
$parsed_info=array(); 
$parsed_info['literal']=$interestingdomnode->getElementsByTagName("literal")->item(0)->textContent; 
foreach($interestingdomnode->getElementsByTagName("cp_value") as $cp){ 
$parsed_info["cp_type-".$cp->cp_type]=$cp->textContent 
} 
foreach($interestingdomnode->getElementsByTagName("rad_type") as $cp){ 
$parsed_info["rad_type-".$cp->rad_type]=$cp->textContent 
} 
$parsed_info['meaning']=''; 
foreach($interestingdomnode->getElementsByTagName("meaning") as $cp){ 
$parsed_info['meaning'].=$cp->textContent.PHP_EOL; 
} 
var_dump($parsed_info); 
+0

그 행을 따라 가면 좋겠지 만 불행하게도 더 많거나 적은 필드를 가질 수있는 노드를 다루고 있습니다 , 다른 이름, 그래서 구조를 하드 코딩 싶지 않았어. 나는 더 추상적이고 유연한 것을 원했다. – KiaiFighter

+0

oh..sorry, 나는 그것을 이해하기에는 너무 피곤하지만, $ domnode-> 속성을 ​​반복해야한다고 생각합니다. – hanshenrik

+0

지금 알아 냈습니다! 영감을 가져 주셔서 감사합니다! – KiaiFighter

관련 문제