diff --git a/src/PhpSpreadsheet/Reader/Xml.php b/src/PhpSpreadsheet/Reader/Xml.php
index 11aa1df3bd..9de882337f 100644
--- a/src/PhpSpreadsheet/Reader/Xml.php
+++ b/src/PhpSpreadsheet/Reader/Xml.php
@@ -191,7 +191,7 @@ public function listWorksheetNames($pFilename)
$xml_ss = $xml->children($namespaces['ss']);
foreach ($xml_ss->Worksheet as $worksheet) {
- $worksheet_ss = $worksheet->attributes($namespaces['ss']);
+ $worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']);
$worksheetNames[] = (string) $worksheet_ss['Name'];
}
@@ -221,7 +221,7 @@ public function listWorksheetInfo($pFilename)
$worksheetID = 1;
$xml_ss = $xml->children($namespaces['ss']);
foreach ($xml_ss->Worksheet as $worksheet) {
- $worksheet_ss = $worksheet->attributes($namespaces['ss']);
+ $worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']);
$tmpInfo = [];
$tmpInfo['worksheetName'] = '';
@@ -381,13 +381,13 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
}
if (isset($xml->CustomDocumentProperties)) {
foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) {
- $propertyAttributes = $propertyValue->attributes($namespaces['dt']);
+ $propertyAttributes = self::getAttributes($propertyValue, $namespaces['dt']);
$propertyName = preg_replace_callback('/_x([0-9a-f]{4})_/i', ['self', 'hex2str'], $propertyName);
$propertyType = Properties::PROPERTY_TYPE_UNKNOWN;
switch ((string) $propertyAttributes) {
case 'string':
$propertyType = Properties::PROPERTY_TYPE_STRING;
- $propertyValue = trim($propertyValue);
+ $propertyValue = trim((string) $propertyValue);
break;
case 'boolean':
@@ -407,7 +407,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
break;
case 'dateTime.tz':
$propertyType = Properties::PROPERTY_TYPE_DATE;
- $propertyValue = strtotime(trim($propertyValue));
+ $propertyValue = strtotime(trim((string) $propertyValue));
break;
}
@@ -420,8 +420,9 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
$worksheetID = 0;
$xml_ss = $xml->children($namespaces['ss']);
- foreach ($xml_ss->Worksheet as $worksheet) {
- $worksheet_ss = $worksheet->attributes($namespaces['ss']);
+ foreach ($xml_ss->Worksheet as $worksheetx) {
+ $worksheet = ($worksheetx === null) ? new SimpleXMLElement('') : $worksheetx;
+ $worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']);
if (
(isset($this->loadSheetsOnly)) && (isset($worksheet_ss['Name'])) &&
@@ -444,7 +445,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
// locally scoped defined names
if (isset($worksheet->Names[0])) {
foreach ($worksheet->Names[0] as $definedName) {
- $definedName_ss = $definedName->attributes($namespaces['ss']);
+ $definedName_ss = self::getAttributes($definedName, $namespaces['ss']);
$name = (string) $definedName_ss['Name'];
$definedValue = (string) $definedName_ss['RefersTo'];
$convertedValue = AddressHelper::convertFormulaToA1($definedValue);
@@ -458,7 +459,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
$columnID = 'A';
if (isset($worksheet->Table->Column)) {
foreach ($worksheet->Table->Column as $columnData) {
- $columnData_ss = $columnData->attributes($namespaces['ss']);
+ $columnData_ss = self::getAttributes($columnData, $namespaces['ss']);
if (isset($columnData_ss['Index'])) {
$columnID = Coordinate::stringFromColumnIndex((int) $columnData_ss['Index']);
}
@@ -475,14 +476,14 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
$additionalMergedCells = 0;
foreach ($worksheet->Table->Row as $rowData) {
$rowHasData = false;
- $row_ss = $rowData->attributes($namespaces['ss']);
+ $row_ss = self::getAttributes($rowData, $namespaces['ss']);
if (isset($row_ss['Index'])) {
$rowID = (int) $row_ss['Index'];
}
$columnID = 'A';
foreach ($rowData->Cell as $cell) {
- $cell_ss = $cell->attributes($namespaces['ss']);
+ $cell_ss = self::getAttributes($cell, $namespaces['ss']);
if (isset($cell_ss['Index'])) {
$columnID = Coordinate::stringFromColumnIndex((int) $cell_ss['Index']);
}
@@ -524,7 +525,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
$cellData = $cell->Data;
$cellValue = (string) $cellData;
$type = DataType::TYPE_NULL;
- $cellData_ss = $cellData->attributes($namespaces['ss']);
+ $cellData_ss = self::getAttributes($cellData, $namespaces['ss']);
if (isset($cellData_ss['Type'])) {
$cellDataType = $cellData_ss['Type'];
switch ($cellDataType) {
@@ -587,7 +588,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
$author = (string) $commentAttributes->Author;
}
$node = $cell->Comment->Data->asXML();
- $annotation = strip_tags($node);
+ $annotation = strip_tags((string) $node);
$spreadsheet->getActiveSheet()->getComment($columnID . $rowID)->setAuthor($author)->setText($this->parseRichText($annotation));
}
@@ -610,7 +611,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
if ($rowHasData) {
if (isset($row_ss['Height'])) {
$rowHeight = $row_ss['Height'];
- $spreadsheet->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight);
+ $spreadsheet->getActiveSheet()->getRowDimension($rowID)->setRowHeight((float) $rowHeight);
}
}
@@ -631,7 +632,7 @@ public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
$activeWorksheet = $spreadsheet->setActiveSheetIndex(0);
if (isset($xml->Names[0])) {
foreach ($xml->Names[0] as $definedName) {
- $definedName_ss = $definedName->attributes($namespaces['ss']);
+ $definedName_ss = self::getAttributes($definedName, $namespaces['ss']);
$name = (string) $definedName_ss['Name'];
$definedValue = (string) $definedName_ss['RefersTo'];
$convertedValue = AddressHelper::convertFormulaToA1($definedValue);
@@ -662,10 +663,11 @@ private function parseStyles(SimpleXMLElement $xml, array $namespaces): void
}
foreach ($xml->Styles[0] as $style) {
- $style_ss = $style->attributes($namespaces['ss']);
+ $style_ss = self::getAttributes($style, $namespaces['ss']);
$styleID = (string) $style_ss['ID'];
$this->styles[$styleID] = (isset($this->styles['Default'])) ? $this->styles['Default'] : [];
- foreach ($style as $styleType => $styleData) {
+ foreach ($style as $styleType => $styleDatax) {
+ $styleData = $styleDatax ?? new SimpleXMLElement('');
$styleAttributes = $styleData->attributes($namespaces['ss']);
switch ($styleType) {
case 'Alignment':
@@ -750,15 +752,16 @@ private function parseStyleBorders($styleID, SimpleXMLElement $styleData, array
$diagonalDirection = '';
$borderPosition = '';
foreach ($styleData->Border as $borderStyle) {
- $borderAttributes = $borderStyle->attributes($namespaces['ss']);
+ $borderAttributes = self::getAttributes($borderStyle, $namespaces['ss']);
$thisBorder = [];
$style = (string) $borderAttributes->Weight;
$style .= strtolower((string) $borderAttributes->LineStyle);
$thisBorder['borderStyle'] = self::$mappings['borderStyle'][$style] ?? Border::BORDER_NONE;
- foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) {
+ foreach ($borderAttributes as $borderStyleKey => $borderStyleValuex) {
+ $borderStyleValue = (string) $borderStyleValuex;
switch ($borderStyleKey) {
case 'Position':
- $borderStyleValue = strtolower((string) $borderStyleValue);
+ $borderStyleValue = strtolower($borderStyleValue);
if (in_array($borderStyleValue, self::$borderPositions)) {
$borderPosition = $borderStyleValue;
} elseif ($borderStyleValue == 'diagonalleft') {
@@ -784,6 +787,11 @@ private function parseStyleBorders($styleID, SimpleXMLElement $styleData, array
}
}
+ private static function getAttributes(?SimpleXMLElement $simple, string $node): SimpleXMLElement
+ {
+ return ($simple === null) ? new SimpleXMLElement('') : ($simple->attributes($node) ?? new SimpleXMLElement(''));
+ }
+
private static $underlineStyles = [
Font::UNDERLINE_NONE,
Font::UNDERLINE_DOUBLE,
@@ -854,7 +862,8 @@ private function parseStyleFont(string $styleID, SimpleXMLElement $styleAttribut
*/
private function parseStyleInterior($styleID, SimpleXMLElement $styleAttributes): void
{
- foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
+ foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValuex) {
+ $styleAttributeValue = (string) $styleAttributeValuex;
switch ($styleAttributeKey) {
case 'Color':
$this->styles[$styleID]['fill']['endColor']['rgb'] = substr($styleAttributeValue, 1);