Много-много лет мучались с этим. У битрикса есть CIBlockElement::GetList. Последним параметром этой функции можно определить массив возвращаемых полей, что значительно ускоряет работу скрипта, если совместно с этим потом использовать метод GetNext, при парсинге данных. Однако, если задать туда DETAIL_PAGE_URL, то его возвращало с незамененными парметрами. Заменить не сложно, но если в урле используется код раздела, то тогда нужно вызавать CIBlockSection и все скорости теряются.

В тоже время если ничего функции не говорить, то она спокойно возвращает все-все поля и среди них DETAIL_PAGE_URL нормально обработан.

Вот и выяснилось, что чтобы возвращало нормально, надо обязательно отсылать в списке требуемыйх полей: ”LANG_DIR”, “IBLOCK_ID”, “ID”