Forum Discussion
Consuming XML web service
- 1 year ago
Finally, I solved it by generating a Power Query loop to fetch all pages automatically, and later adding a counter for consulting only the last page and finally combining them. Here is the complete code:
let BaseUrl = "https://xxxxxxxxxxxxxxxxxx", // Función para obtener la página de datos GetPage = (pageNumber) => let // Realiza la solicitud con los parámetros adecuados Response = Web.Contents(BaseUrl, [Query=[page=Number.ToText(pageNumber)]]), // Convierte la respuesta XML en una tabla Data = Xml.Tables(Response), // La primera tabla contiene los parámetros de la consulta (paginación y demás) RequestInfo = Data{0}[Table], ExpandedFilter = Table.ExpandTableColumn(RequestInfo, "filter", {"effective_date", "changed_on_or_after", "changed_before", "change_type", "deleted", "only_deleted", "page", "max_page_size", "actual_page_size", "more_pages"}, {"effective_date", "changed_on_or_after", "changed_before", "change_type", "deleted", "only_deleted", "page", "max_page_size", "actual_page_size", "more_pages"}), // La segunda tabla contiene los datos DataTable = Data{1}[Table], Table1 = DataTable[Table], // Expande la tabla de datos ExpandedDataTable = Table.SelectColumns(ExpandedFilter, {"page", "more_pages"}), // Devuelve los datos junto con la información de la paginación PageData = [Data = DataTable, Pagination = ExpandedDataTable] in PageData, // Generar la lista de todas las páginas de datos AllData = List.Generate(// Estado inicial con la primera página () => [Page = Number.FromText(GetPage(1)[Pagination][page]{0}), Data = GetPage(1)[Data], MorePages = GetPage(1)[Pagination][more_pages]{0}], // Condición de continuidad: continuar mientras MorePages sea 1 (hay más páginas) each Number.FromText([MorePages]) = 1, each // Actualización del estado: aumentar la página y obtener los datos correspondientes let NextPage = [Page] + 1, PageData = GetPage(NextPage), NewMorePages = PageData[Pagination][more_pages]{0} in [Page = NextPage, Data = PageData[Data], MorePages = NewMorePages], // Extraer los datos de cada página each [Data] ), // Para capturar el núnmero de páginas, execptuando la última Contador = List.Count(AllData), // Combinar las tablas de datos de cada página en una tabla ExpandedData = Table.Combine(AllData), // Combinar y Expandir todas las tablas de registros Table1 = Table.Combine(ExpandedData[Table]), //Utilizo el contador para acceder a la última página LastPage = [Data = GetPage(Contador + 1)[Data], MorePages = GetPage(Contador + 1)[Pagination][more_pages]{0}], AllData2 = LastPage[Data], Table2 = AllData2{0}[Table], // Combinar las tablas de la primera parte con la tabla de la ultima página CombinedData = Table.Combine({Table1, Table2}), in CombinedData
YCastano
Table1 = DataTable{0}[Table] seems to be extracting the first row of DataTable as a table. Make sure that this extraction is correct.
Have a look at this part in Li.Generate MorePages = GetPage(1)[Pagination][more_pages]{0}
MorePages to be a binary value (1 or 0) indicating whether there are more pages
In the line ExpandedDataTable = Table.ExpandRecordColumn(RequestInfo, "filter", {"page", "max_page_size", "actual_page_size", "more_pages"}), you're expanding RequestInfo to include pagination data (page, max_page_size, actual_page_size, more_pages). This is fine, but check if all these columns exist in your response XML, as missing columns could lead to errors.
I have modified the code
let
BaseUrl = "https://xxxxxxxxxx",
// Función para obtener la página de datos
GetPage = (pageNumber) =>
let
// Realiza la solicitud con los parámetros adecuados
Response = Web.Contents(BaseUrl, [Query=[page=Number.ToText(pageNumber), max_page_size="1000"]]),
// Convierte la respuesta XML en una tabla
Data = Xml.Tables(Response),
// La primera tabla contiene los parámetros de la consulta (paginación y demás)
RequestInfo = Data{0}[Table],
ExpandedFilter = Table.ExpandTableColumn(RequestInfo, "filter", {"effective_date", "changed_on_or_after", "changed_before", "change_type", "deleted", "only_deleted", "page", "max_page_size", "actual_page_size", "more_pages"}, {"effective_date", "changed_on_or_after", "changed_before", "change_type", "deleted", "only_deleted", "page", "max_page_size", "actual_page_size", "more_pages"}),
// La segunda tabla contiene los datos
DataTable = Data{1}[Table],
Table1 = DataTable[Table],
// Expande la tabla de datos
ExpandedDataTable = Table.SelectColumns(ExpandedFilter, {"page", "max_page_size", "actual_page_size", "more_pages"}),
// Devuelve los datos junto con la información de la paginación
PageData = [Data = DataTable, Pagination = ExpandedDataTable]
in
PageData,
// Generar la lista de todas las páginas de datos
AllData = List.Generate(// Estado inicial con la primera página#
() => [Page = Number.FromText(GetPage(1)[Pagination][page]{0}), Data = GetPage(1)[Data], MorePages = GetPage(1)[Pagination][more_pages]{0}],
// Condición de continuidad: continuar mientras MorePages sea 1 (hay más páginas)
each Number.FromText([MorePages]) = 1,
each // Actualización del estado: aumentar la página y obtener los datos correspondientes
let
NextPage = [Page] + 1,
PageData = GetPage(NextPage),
NewMorePages = PageData[Pagination][more_pages]{0}
in
[Page = NextPage, Data = PageData[Data], MorePages = NewMorePages],
// Extraer los datos de cada página
each [Data]
),
// Combinar las tablas de datos de cada página en una tabla
ExpandedData = Table.Combine(AllData),
// Combinar y Expandir todas las tablas de registros
CombinedData = Table.Combine(ExpandedData[Table]),
Results = Table.SelectRows(CombinedData, each ([unidadorg] <> ""))
in
Results
and proved that the GetData function works well, it generates the following:
Now I'm leaving out the last page of the web service (page 10), since it has the value [more_pages] = 0. How can I include it?