Özelliklerine göre XML bir yapı filtreleme

2 Cevap php

I have a nested simple XML structure that I load with PHP's simpleXML. Some elements of the structure contain "context" attributes.

<tab context="new_item, edit_item">
  <input type="text" context="new_item">   
  <input type="readonly" context="edit_item">
    <tab context="new_item">
    ...
    </tab>
</tab>

Yüklemeden sonra, ben geçerli bağlama ait olmayan bütün unsurlarından yapısını temizlemek gerekir.

Ben tabii her elemanın geçerken olabilir ama belki birileri hızlı, SimpleXML yol bilir - belki XPath ile - buna yapısını filtre?

"Bağlam" değerleri virgülle ayrılmış listesi, ancak ben bir daha parseable forma değiştirmek olabilir unutmayın:

context_new_item="yes" context_edit_item = "no"

Gerekirse.

Ben kendimi sadece PHP belgelerin en geniş parçası değil, şimdi SimpleXML belgelerine eleyerek ediyorum ...

Update: Bu konu neredeyse 13 dakika eski ve "SimpleXML filtreleme" için Google'da zaten 2. Lanet olsun, ben etkilendim.

2 Cevap

Eğer tüm belge süzülmeye varsa XPath gitmek için yoludur. Sorun SimpleXML böyle keyfi düğümleri kaldırmak değil, bu nedenle convert them to DOM daha sonra kullanmak parentNode-> removeChild olurdu () olduğunu

Ben şeyler bu tür yapan bir kütüphane maintening, SimpleDOM. Am İşte ben bunu istiyorum nasıl:

include 'SimpleDOM.php';

$tab = simpledom_load_string(
    '<tab context="new_item,edit_item">
      <input type="text" context="new_item" />
      <input type="readonly" context="edit_item" />
        <tab context="new_item">
        ...
        </tab>
    </tab>'
);

$context = 'new_item';

// will match ",new_item," to ",new_item,edit_item,"
$tab->deleteNodes('//*[contains(concat(",", @context, ","), ",' . $context . ',")]');

echo $tab->asXML();

Bu belge geçersiz kılacak gibi, not kök düğümünü silineceğini unutmayın. Eğer harici bir kütüphaneye bağlıdır istemiyorsanız, kaynak kodu ve ne gerek kopyala / yapıştır bakmak için çekinmeyin.

XPath ifadesi hakkında bir not: virgül ile ayrılır ise, virgül (boşluk) daha başka bir şey olmadığından emin olun ve niteliğin değerini ve virgüller arasında onu eşleşen konum değerini hem de içine.

Eğer PHP uygulamalarında "bağlam" değeri varsa, seçmek olabilir:

$context = "new_item";
$xpath = "//*[not(contains(concat(',', normalize-space(@context), ','), ',$context,'))]";

Şimdi istenen bağlamda not her şeyi seçtiniz.

Şimdi bu yapıyı olsaydı:

<tab context="new_item, edit_item">
  <context name="new_item" />
  <context name="edit_item" />
  <input type="text">
    <context name="new_item" />
  </input>
  <input type="readonly">
    <context name="edit_item" />
  </input>
  <tab>
    <context name="new_item" />
    ...
  </tab>
</tab>

Bunu daha basit ve daha verimli yapabilirsiniz:

$context = "new_item";
$xpath = "//*[not(context[@name='new_item'])]";

Mümkün bağlamları sayısı sınırlı olup olmadığını da özel özelliklerini kullanabilirsiniz.

$context = "new_item";
$xpath = "//*[not(context_$context = 'yes')]";