簡體   English   中英

如何使用PHP SimpleDOM對XML子節點值進行排序? (或任何其他方法)

[英]How can I sort on XML child node value with PHP SimpleDOM? (or any other method)

我需要根據其子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){ ... }

以及其他各種類似的“ sort”值,例如“ @MajorDescription”,“ / MajorDescription”和“。”。 如此處所建議, 如何使用SimpleDOM sortedXPath對節點值進行排序? 但是當我使用var_dump()檢查它時,一切都會返回一個空數組

我認為問題是我需要對子節點的值進行排序-這可能嗎? foreach必須位於ProgramList上,因為我需要在每次迭代中輸出ProgramList中所有子節點的值。

有什么建議么? 我不必使用SimpleDOM,對任何有效的方法都可以使用-當前,我正在遍歷AZ數組,並且對於每個字母,都對ProgramList進行了迭代,將MajorDescription的第一個字母與當前字母進行比較,然后如果匹配則輸出-這顯然不是理想的選擇,只能對首字母進行排序...

您可以嘗試將所有ProgramList元素放入數組,然后根據自定義函數對其進行排序。 該代碼應如下所示:

function cmp($a, $b)
{
  return strcmp($a->MajorDescription[0],$b->MajorDescription[0])
}

$arr = $listxml->xpath("//ArrayOfProgramList/ProgramList");
usort($arr,"cmp");

您的原始代碼有兩個問題。 首先是XML使用默認名稱空間,並且XPath在設計上不支持默認名稱空間,因此您必須查找名稱空間節點(例如//foo:bar ,而不是//bar )才能找到它們。 如果您無法為此名稱空間注冊前綴(例如,如果您無法修改源XML),則可以使用通配符//*以及與節點名稱空間和/或本地名稱匹配的謂詞來匹配名稱空間節點。

$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";
}

另一個問題是您的排序標准。 它應該從目標節點的上下文中寫入。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM