2014-10-14 7 views
0

Я получаю XML-блок через POST. Я хотел бы разобрать конкретный AttributeValue, где AttributeId равен urn:Cisco:uc:1.0:callingnumber.выберите узлы XML по атрибуту родительского узла

Вот данные я получаю через POST:

<?xml version="1.0" encoding="UTF-8"?> 
<Request xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os"> 
<Subject SubjectCategory="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"> 
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:role-id" 
DataType="http://www.w3.org/2001/XMLSchema#string" Issuer="requestor"> 
<AttributeValue>CISCO:UC:UCMPolicy</AttributeValue> 
</Attribute> 
<Attribute AttributeId="urn:Cisco:uc:1.0:callingnumber" DataType="http://www.w3.org/2001/XMLSchema#string"> 
<AttributeValue>89996203741</AttributeValue> 
</Attribute> 
<Attribute AttributeId="urn:Cisco:uc:1.0:callednumber" 
DataType="http://www.w3.org/2001/XMLSchema#string"> 
<AttributeValue>95551231234</AttributeValue> 
</Attribute> 
<Attribute AttributeId="urn:Cisco:uc:1.0:transformedcgpn" 
DataType="http://www.w3.org/2001/XMLSchema#string"> 
<AttributeValue>89996203741</AttributeValue> 
</Attribute> 
<Attribute AttributeId="urn:Cisco:uc:1.0:transformedcdpn" 
DataType="http://www.w3.org/2001/XMLSchema#string"> 
<AttributeValue>95551231234</AttributeValue> 
</Attribute> 
</Subject> 
<Resource> 
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" 
DataType="http://www.w3.org/2001/XMLSchema#anyURI"> 
<AttributeValue>CISCO:UC:VoiceOrVideoCall</AttributeValue> 
</Attribute> 
</Resource> 
<Action> 
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" 
DataType="http://www.w3.org/2001/XMLSchema#anyURI"> 
<AttributeValue>any</AttributeValue> 
</Attribute> 
</Action> 
<Environment> 
<Attribute AttributeId="urn:Cisco:uc:1.0:triggerpointtype" 
DataType="http://www.w3.org/2001/XMLSchema#string"> 
<AttributeValue>translationpattern</AttributeValue> 
</Attribute> 
</Environment> 
</Request> 

И то, что я пытался до сих пор:

<?php 
$datarequest = trim(file_get_contents('php://input')); 
$xmlrequest = simplexml_load_string($datarequest); 
$root=$xmlrequest->Subject; 


foreach($root->Attribute as $child) 
    { 
    echo $child->AttributeValue . "<br>"; 
    } 
?> 

Это вернет мне все AttributeValue результаты в Subject разделе результата , Как добавить условные критерии в мой цикл foreach, чтобы он возвращал результаты только там, где AttributeId="urn:Cisco:uc:1.0:callingnumber?

ответ

0

SimpleXML довольно ошибочно назван, поскольку (IMO) это сложнее, чем использование PHP DOM. Вот реализация вашего запроса с использованием DOMDocument и DOMXPath; XPath является очень простым способом найти узлы, основанные на имена тегов, значениях или атрибутов - намного проще, что перебор документа и поиск для детей и т.д.

# load the XML into a new DOMDocument object 
$dom = new DOMDocument; 
$dom->loadXML($xml); 

# create a new DOMXPath object 
$xp = new DOMXPath($dom); 
# register the namespace (given in the <Request> element) 
$xp->registerNamespace("o", "urn:oasis:names:tc:xacml:2.0:context:schema:os"); 

# search for AttributeValue nodes with parent Attribute elements 
# with that AttributeId. Note that all the node names have to be prefixed with 
# the namespace 
$nodes = $xp->query("//o:Attribute[@AttributeId='urn:Cisco:uc:1.0:callingnumber']/o:AttributeValue"); 

# go through the results and do whatever you want with them 
foreach ($nodes as $n) { 
    echo $n->nodeName . " node contents: " . $n->nodeValue . "\n"; 
} 

Выхода для документа вы вывесили:

AttributeValue node contents: 89996203741 
+0

Я закончил с использованием своего подхода с помощью DOM Я думаю, вопрос в том, что является преимущество/недостаток использования DOM против пути @bernie построил его с помощью "simplexml_load_string? – rsaturns

+0

Я думаю, что DOM проще в использовании, чем simplexml - он более гибкий, документация лучше, и вы можете использовать 'print_r ($ node)', чтобы легко просматривать содержимое узла. –

0

Следуя непосредственно из я встревожен чужеродного ответа «ы (что я чувствую, это лучший способ приблизиться к этому), вы можете использовать очень похожий код подход с использованием XPath, однако пока еще с использованием SimpleXML.

// populate $datarequest (as per question) 
$datarequest = trim(file_get_contents('php://input')); 

// load the XML via SimpleXML 
$xmlrequest = simplexml_load_string($datarequest); 

// register the name space 
$xmlrequest->registerXPathNamespace("o", "urn:oasis:names:tc:xacml:2.0:context:schema:os"); 

// xpath query to find a particular Attribute node that contains an AttributeId as specified in question 
$xpath_result = $xmlrequest->xpath("//o:Attribute[@AttributeId='urn:Cisco:uc:1.0:callingnumber']/o:AttributeValue"); 

// grab the first result (xpath_result will return an array) 
// and cast to a string. Alternatively, you could loop through 
// the results if you're expecting more than one match 
$result = ''; 
if (isset($xpath_result[0])) { 
    $result = (string)$xpath_result[0]; 
} 

// will output '89996203741' 
print $result; 
Смежные вопросы