我有一个嵌套的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>
问题是并非所有[character]节点都具有完全相同的子节点。
我试图将属性键和值组合成一个键,然后将该值作为值关联。如果没有属性,我想使用标签名称作为密钥。此外,一些孩子具有相同的名称,没有属性。在这种情况下,我想将它们放在由换行符分隔的一个字段中。谢谢!
["literal"] => "name",
["cp_type-ucs"] => "4e9c",
["cp_type-jis208"] => "16-01",
["rad_type-classical"] => "7",
["rad_type-nelson_c"] => "1",
["meaning"] => "this\nthat"
那是我要输出的数组......
任何和所有帮助将不胜感激!谢谢!
编辑:添加了一些代码,我可以使用它遍历各个层并获取标记名称以回显,但由于某种原因,它们不会填充数组。只有“character”标签才会出现在数组中。 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 ) );
编辑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 :(得分: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);