33namespace PhpOffice \Math \Reader ;
44
55use DOMDocument ;
6- use DOMElement ;
6+ use DOMNode ;
77use DOMXPath ;
88use Exception ;
99use PhpOffice \Math \Element ;
1010use PhpOffice \Math \Math ;
1111
1212class OfficeMathML implements ReaderInterface
1313{
14+ /** @var DOMDocument */
15+ protected $ dom ;
16+
1417 /** @var Math */
1518 protected $ math ;
1619
17- /** @var XMLReader */
18- protected $ xmlReader ;
19-
2020 /** @var DOMXpath */
2121 protected $ xpath ;
2222
@@ -46,11 +46,13 @@ public function read(string $content): ?Math
4646 /**
4747 * @see https://devblogs.microsoft.com/math-in-office/officemath/
4848 * @see https://learn.microsoft.com/fr-fr/archive/blogs/murrays/mathml-and-ecma-math-omml
49+ *
50+ * @param Math|Element\AbstractGroupElement $parent
4951 */
50- protected function parseNode (?DOMElement $ nodeRowElement , $ parent ): void
52+ protected function parseNode (?DOMNode $ nodeRowElement , $ parent ): void
5153 {
5254 $ this ->xpath = new DOMXpath ($ this ->dom );
53- foreach ($ this ->xpath ->query ('* ' , $ nodeRowElement ) as $ nodeElement ) {
55+ foreach ($ this ->xpath ->query ('* ' , $ nodeRowElement ) ?: [] as $ nodeElement ) {
5456 $ element = $ this ->getElement ($ nodeElement );
5557 $ parent ->add ($ element );
5658
@@ -60,27 +62,27 @@ protected function parseNode(?DOMElement $nodeRowElement, $parent): void
6062 }
6163 }
6264
63- protected function getElement (DOMElement $ nodeElement ): Element \AbstractElement
65+ protected function getElement (DOMNode $ nodeElement ): Element \AbstractElement
6466 {
6567 switch ($ nodeElement ->nodeName ) {
6668 case 'm:f ' :
6769 $ element = new Element \Fraction ();
6870 // Numerator
6971 $ nodeNumerator = $ this ->xpath ->query ('m:num/m:r/m:t ' , $ nodeElement );
70- if ($ nodeNumerator ->length == 1 ) {
72+ if ($ nodeNumerator && $ nodeNumerator ->length == 1 ) {
7173 $ value = $ nodeNumerator ->item (0 )->nodeValue ;
7274 if (is_numeric ($ value )) {
73- $ element ->setNumerator (new Element \Numeric ($ value ));
75+ $ element ->setNumerator (new Element \Numeric (floatval ( $ value) ));
7476 } else {
7577 $ element ->setNumerator (new Element \Identifier ($ value ));
7678 }
7779 }
7880 // Denominator
7981 $ nodeDenominator = $ this ->xpath ->query ('m:den/m:r/m:t ' , $ nodeElement );
80- if ($ nodeDenominator ->length == 1 ) {
82+ if ($ nodeDenominator && $ nodeDenominator ->length == 1 ) {
8183 $ value = $ nodeDenominator ->item (0 )->nodeValue ;
8284 if (is_numeric ($ value )) {
83- $ element ->setDenominator (new Element \Numeric ($ value ));
85+ $ element ->setDenominator (new Element \Numeric (floatval ( $ value) ));
8486 } else {
8587 $ element ->setDenominator (new Element \Identifier ($ value ));
8688 }
@@ -89,18 +91,19 @@ protected function getElement(DOMElement $nodeElement): Element\AbstractElement
8991 return $ element ;
9092 case 'm:r ' :
9193 $ nodeText = $ this ->xpath ->query ('m:t ' , $ nodeElement );
92- if ($ nodeText ->length == 1 ) {
94+ if ($ nodeText && $ nodeText ->length == 1 ) {
9395 $ value = trim ($ nodeText ->item (0 )->nodeValue );
9496 if (in_array ($ value , $ this ->operators )) {
9597 return new Element \Operator ($ value );
9698 }
9799 if (is_numeric ($ value )) {
98- return new Element \Numeric ($ value );
100+ return new Element \Numeric (floatval ( $ value) );
99101 }
100102
101103 return new Element \Identifier ($ value );
102104 }
103- break ;
105+
106+ return new Element \Identifier ('' );
104107 case 'm:oMath ' :
105108 return new Element \Row ();
106109 default :
0 commit comments