Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix xml numbers decoding #83

Merged
merged 2 commits into from
Oct 25, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Serializer/FiasSerializer.php
Original file line number Diff line number Diff line change
@@ -51,7 +51,11 @@ public function __construct(?array $normalizers = null, ?array $encoders = null)

if ($encoders === null) {
$encoders = [
new XmlEncoder(),
new XmlEncoder(
[
XmlEncoder::TYPE_CAST_ATTRIBUTES => false,
]
),
];
}

62 changes: 28 additions & 34 deletions src/XmlReader/BaseXmlReader.php
Original file line number Diff line number Diff line change
@@ -10,47 +10,48 @@
/**
* Объект, который читает данные из xml файла с помощью XmlReader.
*/
class BaseXmlReader implements XmlReaderInterface
final class BaseXmlReader implements XmlReaderInterface
{
private const XML_READER_CHARSET = 'UTF-8';
private const XML_READER_PARAMS = \LIBXML_COMPACT | \LIBXML_NONET | \LIBXML_NOBLANKS;

/**
* Файл, который открыт в данный момент.
*/
protected ?\SplFileInfo $file = null;
private ?\SplFileInfo $file = null;

/**
* Xpath, по которому следует искать данные.
*/
protected string $xpath = '';
private string $xpath = '';

/**
* Объект XMLReader для чтения документа.
*/
protected ?\XMLReader $reader = null;
private ?\XMLReader $reader = null;

/**
* Текущее смещение внутри массива.
*/
protected int $position = 0;
private int $position = 0;

/**
* Флаг, который указывает, что данные были прочитаны в буфер.
*/
protected bool $isBufferFull = false;
private bool $isBufferFull = false;

/**
* Массив с буфером, для isValid и current.
*/
protected ?string $buffer = null;
private ?string $buffer = null;

/**
* {@inheritdoc}
*/
public function open(\SplFileInfo $file, string $xpath): bool
{
if (!$file->isFile() || !$file->isReadable()) {
throw new XmlException(
"File '" . $file->getPathname() . "' isn't readable or doesn't exist"
);
throw XmlException::create("File '%s' isn't readable or doesn't exist", $file->getPathname());
}

$this->file = $file;
@@ -132,26 +133,16 @@ public function valid(): bool
return $this->buffer !== null;
}

/**
* Деструктор.
*
* Закрывает файл, если он все еще открыт.
*/
public function __destruct()
{
$this->close();
}

/**
* Возвращает строку из файла, соответствующую элементу, или null, если разбор
* файла завершен.
*
* @throws XmlException
*/
protected function getLine(): ?string
private function getLine(): ?string
{
if (!$this->reader) {
throw new XmlException('Reader and xpath must be set before reading');
throw XmlException::create('Reader and xpath must be set before reading');
}

$return = null;
@@ -170,9 +161,9 @@ protected function getLine(): ?string
$this->reader->next();
}
} catch (\Throwable $e) {
$fileName = $this->file ? $this->file->getPathname() : '';
$message = "Error while parsing xml '{$fileName}' by '{$this->xpath}' path.";
throw new XmlException($message, 0, $e);
$fileName = $this->file?->getPathname() ?? '';
$message = "Error while parsing xml '{$fileName}' by '{$this->xpath}' path";
throw new XmlException(message: $message, previous: $e);
}

return $return;
@@ -182,7 +173,7 @@ protected function getLine(): ?string
* Пропускает все xml элементы в текущем ридере, у которых имя или вложенность
* не совпадают с указанным параметром.
*/
protected function skipUselessXml(string $nodeName, int $nodeDepth): void
private function skipUselessXml(string $nodeName, int $nodeDepth): void
{
while (
$this->reader
@@ -207,7 +198,7 @@ protected function skipUselessXml(string $nodeName, int $nodeDepth): void
*
* @throws XmlException
*/
protected function seekXmlPath(): bool
private function seekXmlPath(): bool
{
$reader = $this->resetReader();

@@ -238,19 +229,22 @@ protected function seekXmlPath(): bool
*
* @throws XmlException
*/
protected function resetReader(): \XMLReader
private function resetReader(): \XMLReader
{
if (!$this->file || !$this->xpath) {
throw new XmlException("File doesn't open.");
throw XmlException::create("File doesn't open");
}

$this->unsetReader();
$this->reader = new \XMLReader();

if ($this->reader->open($this->file->getPathname(), 'UTF-8', \LIBXML_COMPACT | \LIBXML_NONET | \LIBXML_NOBLANKS) === false) {
throw new XmlException(
"Can't open file '" . $this->file->getPathname() . "' for reading."
);
$res = $this->reader->open(
$this->file->getPathname(),
self::XML_READER_CHARSET,
self::XML_READER_PARAMS
);
if ($res === false) {
throw XmlException::create("Can't open file '%s' for reading", $this->file->getPathname());
}

return $this->reader;
@@ -259,7 +253,7 @@ protected function resetReader(): \XMLReader
/**
* Закрывает открытые ресурсы и сбрасывает все внутренние счетчики.
*/
protected function unsetReader(): void
private function unsetReader(): void
{
if ($this->reader) {
$this->reader->close();
4 changes: 2 additions & 2 deletions tests/src/Serializer/FiasSerializerTest.php
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ public function testDenormalize(): void
ACTSTATID="2"
NAME="Не актуальный"
TESTDATE="2019-10-10T10:10:10.02"
KOD_T_ST="10"
KOD_T_ST="227010000010000016740025000000000"
EMPTYSTRINGINT=""
/>
EOT;
@@ -41,7 +41,7 @@ public function testDenormalize(): void
$this->assertInstanceOf(FiasSerializerMock::class, $object);
$this->assertSame(2, $object->getActstatid());
$this->assertSame('Не актуальный', $object->getName());
$this->assertSame('10', $object->getKodtst());
$this->assertSame('227010000010000016740025000000000', $object->getKodtst());
$this->assertSame(0, $object->getEmptyStringInt());

$date = $object->getTestDate();
Loading