PHP解析XML数据失败求助:提取指定节点属性
Hey there! Let's sort out this XML parsing problem you're facing. Right now, converting your database result directly to an array with json_decode(json_encode($result), true) only converts the database's result structure into an array—it doesn't actually parse the raw XML string stored in your XML field. That's why you can't access DialingNumber, ConversationDuration, and StartTime directly.
Here's a step-by-step solution using PHP's built-in XML parsing tools:
Step 1: Extract the Raw XML String from Your Database Result
First, pull the actual XML string out of the $result array (since fetchAll() returns a 2D array of rows):
// Get the raw XML string from the first row of your result $xmlString = $result[0]['XML'];
Step 2: Parse the XML with SimpleXML (Simplest Approach)
SimpleXML is perfect for straightforward XML structures. Let's assume your XML looks something like this (adjust the node paths if your structure differs):
<CallRecord> <DialingNumber>123-456-7890</DialingNumber> <ConversationDuration>180</ConversationDuration> <StartTime>2024-05-21 09:15:00</StartTime> </CallRecord>
Use this code to parse and extract the fields:
// Load the XML string into a SimpleXMLElement object $xml = simplexml_load_string($xmlString); // Extract fields (cast to appropriate types to avoid object issues) $dialingNumber = (string)$xml->DialingNumber; $conversationDuration = (int)$xml->ConversationDuration; $startTime = (string)$xml->StartTime; // Verify the output print_r([ 'DialingNumber' => $dialingNumber, 'ConversationDuration' => $conversationDuration, 'StartTime' => $startTime ]);
Step 3: Handle XML with Namespaces (If Applicable)
If your XML uses namespaces (e.g., <CallRecord xmlns="http://your-domain.com/call-data">), you'll need to target the namespace explicitly:
// Get the default namespace from the XML $namespaces = $xml->getNamespaces(true); $callData = $xml->children($namespaces['']); // Use the namespace prefix if not default // Extract fields from the namespace-aware node $dialingNumber = (string)$callData->DialingNumber; $conversationDuration = (int)$callData->ConversationDuration; $startTime = (string)$callData->StartTime;
Alternative: Use DOMDocument for Complex XML
If your XML has a more nested or complex structure, DOMDocument gives you more control:
$dom = new DOMDocument(); $dom->loadXML($xmlString); // Fetch each node and extract its value (handle cases where nodes might be missing) $dialingNumberNode = $dom->getElementsByTagName('DialingNumber')->item(0); $dialingNumber = $dialingNumberNode ? $dialingNumberNode->nodeValue : ''; $durationNode = $dom->getElementsByTagName('ConversationDuration')->item(0); $conversationDuration = $durationNode ? (int)$durationNode->nodeValue : 0; $startTimeNode = $dom->getElementsByTagName('StartTime')->item(0); $startTime = $startTimeNode ? $startTimeNode->nodeValue : ''; // Output the results echo "Dialing Number: $dialingNumber\n"; echo "Conversation Duration: $conversationDuration seconds\n"; echo "Start Time: $startTime\n";
Why Your Original Approach Didn't Work
When you used json_decode(json_encode($result), true), you converted the database's result set (which includes the raw XML string as a value in the array) into a plain array—but the XML itself wasn't parsed. The XML string was just stored as a string in the array, so you couldn't access its internal nodes directly.
Just remember: if your actual XML structure is different from the example (e.g., nodes are nested under parent elements), adjust the node paths in the code to match your XML's hierarchy.
内容的提问来源于stack exchange,提问作者Johan

