我需要根据它的子元素MajorDescription
的值对以下XML(foreach ProgramList)进行排序<ArrayOfProgramList xmlns="http://schemas.datacontract.org/2004/07/Taca.Resources" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ProgramList>
<AreaOfInterests xmlns:a="http://schemas.datacontract.org/2004/07/Taca">
<a:AreaOfInterest>
<a:Interest>ABORIGINAL STUDIES</a:Interest>
</a:AreaOfInterest>
</AreaOfInterests>
<Coop>true</Coop>
<MajorDescription>ABORIGINAL COMMUNITY AND SOCIAL DEVELOPMENT</MajorDescription>
<Program>ACSD</Program>
<ProgramLocations>
<ProgramLocation>
<Campus>Barrie</Campus>
</ProgramLocation>
</ProgramLocations>
<Term>201210</Term>
</ProgramList>
<ProgramList>
<AreaOfInterests xmlns:a="http://schemas.datacontract.org/2004/07/Taca">
<a:AreaOfInterest>
<a:Interest>GRADUATE CERTIFICATE STUDIES</a:Interest>
</a:AreaOfInterest>
<a:AreaOfInterest>
<a:Interest>HEALTH AND WELLNESS STUDIES</a:Interest>
</a:AreaOfInterest>
</AreaOfInterests>
<Coop>false</Coop>
<MajorDescription>ADVANCED CARE PARAMEDIC</MajorDescription>
<Program>PARM</Program>
<ProgramLocations>
<ProgramLocation>
<Campus>Barrie</Campus>
</ProgramLocation>
</ProgramLocations>
<Term>201210</Term>
</ProgramList>
</ArrayOfProgramList>
我正在尝试使用SimpleDOM,因为我已经读过这是在其他SO问题上对XML进行排序的最简单方法。
我尝试过使用:
foreach($listxml->sortedXPath('//ArrayOfProgramList/ProgramList','//ArrayOfProgramList/ProgramList/MajorDescription') as $program){ ... }
以及各种其他类似的'排序'值,例如'@MajorDescription','/ MajorDescription'和'。'正如How does one use SimpleDOM sortedXPath to sort on node value?所建议的那样,当我用var_dump()
检查它时,一切都会返回一个空数组我认为问题在于我需要对子节点的值进行排序 - 这可能吗? foreach需要在ProgramList上,因为我需要在每次迭代时输出ProgramList中所有子节点的值。
有什么建议吗?我不必使用SimpleDOM,我对任何有效的方法都是开放的 - 目前我正在遍历一个AZ数组,并且对于每个字母,迭代ProgramList,将MajorDescription的第一个字母与当前字母进行比较,输出如果匹配 - 这显然是不理想,只对第一个字母排序......
答案 0 :(得分:1)
您可以尝试将所有ProgramList元素放入一个数组中,并根据自定义函数对其进行排序。代码应如下所示:
function cmp($a, $b)
{
return strcmp($a->MajorDescription[0],$b->MajorDescription[0])
}
$arr = $listxml->xpath("//ArrayOfProgramList/ProgramList");
usort($arr,"cmp");
答案 1 :(得分:0)
原始代码存在两个问题。第一个是您的XML使用默认命名空间,并且根据设计,XPath不支持默认命名空间,因此您必须查找命名空间节点(例如//foo:bar
,而不是//bar
)来查找它们。如果您无法为此命名空间注册前缀(例如,如果您无法修改源XML),则可以使用通配符//*
以及与节点的命名空间和/或本地名称匹配的谓词来匹配命名空间节点。 / p>
$nsPredicate = '[namespace-uri() = "http://schemas.datacontract.org/2004/07/Taca.Resources"]';
$query = '//*[local-name() = "ArrayOfProgramList"]' . $nsPredicate
. '/*[local-name() = "ProgramList"]' . $nsPredicate;
$orderBy = '*[local-name() = "MajorDescription"]' . $nsPredicate;
foreach ($listxml->sortedXPath($query, $orderBy) as $program)
{
echo $program->asXML(),"\n";
}
另一个问题是您的排序标准。它应该从目标节点的上下文中编写。