بي إتش بي سيمبل إكس إم إل.كيفية الحصول على العنصر الأخير؟

StackOverflow https://stackoverflow.com/questions/295112

  •  08-07-2019
  •  | 
  •  

سؤال

كيف يمكنني الحصول على العنصر الأخير (أو أي عنصر محدد في هذا الشأن) في كائن simplexml؟افترض أنك لا تعرف عدد العقد الموجودة.

السابق.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/xsl.xml"?>
<obj 
  href="http://xml.foo.com/" 
  display="com.foo.bar" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns="http://obix.org/ns/schema/1.0" 
>
 <list name="data" of="HistoryRecord">
  <obj>
   <abstime name="timestamp" val="1876-11-10T00:00:00-08:00"></abstime>
   <int name="energy_in_kwh" val="1234"></int>
   <int name="energy_out_kwh" val="123456"></int>
  </obj>
  <obj>
   <abstime name="timestamp" val="1876-11-10T00:15:00-08:00"></abstime>
   <int name="energy_in_kwh" val="1335"></int>
   <int name="energy_out_kwh" val="443321"></int>
  </obj>
 </list>
 <int name="count" val="2"></int>
</obj>

وأريد الاستيلاء على الأخير <obj></obj> قطعة (أو حتى جزء منها فقط).

هل كانت مفيدة؟

المحلول

وظيفة last() <ع> استخدام كسباث، والذي يحل هذه المشكلة بالذات:

<?php 
$xml = simplexml_load_file('HistoryRecord.xml'); 
$xml->registerXPathNamespace('o', 'http://obix.org/ns/schema/1.0');

$xpath = "/o:obj/o:list/o:obj[last()]/o:int[@name = 'energy_in_kwh']";
$last_kwh = $xml->xpath($xpath); 
?> 

وهنا يبدو ل<obj> الداخلية الأخيرة، وهنا ل<int> مع اسم "energy_in_kwh".

واحترس من تسجيل مساحة الاسم. (جميع العناصر الخاصة بك هي جزء من مساحة "http://obix.org/ns/schema/1.0"، استعلام XPath يجب أن تعكس ذلك.


وتحرير: لاحظ أن [last()] ما يعادل [position() = last()]

نصائح أخرى

وهناك تعبير XPath التي سوف تفعل بالضبط ما تريد:

$xml='<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/xsl.xml"?>
<obj href="http://xml.foo.com/" display="com.foo.bar" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://obix.org/ns/schema/1.0" >
 <list name="data" of="HistoryRecord">
  <obj>
   <abstime name="timestamp" val="1876-11-10T00:00:00-08:00"></abstime>
   <int name="energy_in_kwh" val="1234"></int>
   <int name="energy_out_kwh" val="123456"></int>
  </obj>
  <obj>
   <abstime name="timestamp" val="1876-11-10T00:15:00-08:00"></abstime>
   <int name="energy_in_kwh" val="1335"></int>
   <int name="energy_out_kwh" val="443321"></int>
  </obj>
 </list>
 <int name="count" val="2"></int>
</obj>';
$x=simplexml_load_string($xml);
$x->registerXPathNamespace('obix', 'http://obix.org/ns/schema/1.0');
$objects=$x->xpath('/obix:obj/obix:list/obix:obj[last()]');
print_r($objects);

وعلى سبيل المثال /bookstore/book[last()] سوف تختار الماضي عنصر الكتاب الذي هو الطفل العنصر بيع الكتب.

وأسرع طريقة للوصول العقد في XML، لمبرمج، هو كسباث. نلقي نظرة على طرق كسباث و <ل أ href = "http://w3schools.com/xpath" يختلط = "نوفولو noreferrer"> كسباث نفسها .

ويمكنك أن تبدأ مع هذا .. عليك أن تكون قادرة على حفر بها .. أنا لا أحب أن استخدموا نفس اسم العلامة في مستويات 2 .. أنا في محاولة لتجنب أسماء العلامات مكررة.

<?php
$s = simplexml_load_file('in.xml');
$s->registerXPathNamespace('obix', 'http://obix.org/ns/schema/1.0');
$items = $s->xpath('//obix:list');
?>

أعتقد أن SimpleXML يقوم بتحميل ملف XML بأكمله على أي حال، و(إذا كنت أتذكر بشكل صحيح) يمكنك استخدام عقد SimpleXML كما لو كانت مصفوفات، لذا يمكنك فقط استخدام وظائف المصفوفة للحصول على العقدة الأخيرة.لقد مر وقت طويل منذ أن استخدمت PHP ولكن يجب أن تكون قادرًا على الحصول على الطول ثم الحصول على العنصر بطول -1...

يحرر:يمكنك بالطبع استخدام XPath أيضًا، وأعتقد أنني يجب أن أذكر ذلك أيضًا ولكني لم أكن متأكدًا من ذلك last() عملت في تنفيذ SimpleXML XPath.

لست متأكدًا من الأسرع، باستخدام فهارس المصفوفة أو XPath، أعتقد أن فهارس المصفوفة كانت أسرع ولكن يجب عليك تجربة كليهما في حلقة عدة آلاف من المرات للحصول على الوقت قبل وبعد الحلقة للتحقق.

ولكن كما هو الحال دائمًا في CS:ما تختاره يعتمد على أشياء كثيرة.

هل الوقت حرج أم أنه يستخدم كثيرًا:ثم ابحث عن الحل الأسرع.

إذا كنت ستحتاج إلى استعلامات أكثر تعقيدًا ولا تمثل السرعة مشكلة:ثم استخدم ما هو أسهل في التنفيذ ويمنحك القوة التي تحتاجها (يعد XPath مفيدًا للتنقل الشجري المعقد، كما أن فهرسة المصفوفات مفيدة للوصول العشوائي السريع في هياكل البيانات من نوع القائمة؛يمكن استخدام XML لكليهما.)

وكما ذكر سابقا، يمكنك استخدام تدوين مجموعة وظائف.

    <?php 
    $xml = simplexml_load_file('HistoryRecord.xml'); 
    $lastObj = $xml->list->obj[$xml->list->obj->count()-1];

أو

    $lastObj = $xml->list->obj[count($xml->list->obj)-1];

ويمكنك أيضا استخدام end() للحصول على العنصر الأخير ولكن فقط إذا كان لديك دائما أكثر من واحد <الكائنات>، وإلا فإنه سيعود نتيجة مختلفة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top