Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
Anonymous
Not applicable

Getting "The name 'Html.Table' does not exist in the current context" in my custom connector project

Hi!

 

I have developed a customer connector for a web service and would like to improve error handling. For that reason I am now handling the different failure HTTP statuses that could occur. I know that the service responds with a simple HTML page in case of an error. I would like to extract the title of that page and present it to the user (e.g. authentication issues).

 

The problem I have is that the parsing of the HTML response is not possible. I get the error "The name 'Html.Table' does not exist in the current context":

 

denisthemenace_0-1601446766797.png

 

 

Here is my code:

 

shared TestSession = (server) =>
let
AuthResp = Web.Contents(server,
[RelativePath="/qcbin/authentication-point/authenticate",
ManualStatusHandling = {400,401,403,404,429,500,502,503}]
),
responseCode = Value.Metadata(AuthResp)[Response.Status],
ErrorMessage = Html.Table(AuthResp, {{"Message", "title"}})
in
if responseCode = 200 then "All good" else ErrorMessage;

 

Anyone who knows why the Function Html.Table is not available in this context?

 

EDIT: I can add that there is no way to build logic around the HTTP status code. The service has some weird implementation which returns additional information in the status code field:

 

HTTP/1.1 401 Failed to authenticate user "xxx", verify your user name and password.
Date: Wed, 30 Sep 2020 07:22:22 GMT

 

The value of 'Response.Status' is empty and I guess it's because of that additional information in the status field that prevents the SDK to extract the correct status value.

 

Thanks and best regards, Denis

1 ACCEPTED SOLUTION

I looked into the power bi code (ILSpy is great 🙂 and figured out that Html.Tables is a built in function, not a Power Query function exactly.  It uses AngleSharp.net under the covers to do the css selectors ect. basically the heavy lifting of the html manipulation / searching.  

 

The following was useful for me, and could be extended to do all the html.table function - it's pretty hacky but got the job done 🙂 

 

MyHtml.Table = (html as text, selectorRecord as any, optional three as any) as any =>
	let
		columnHeader = selectorRecord{0}{0},
		selectorList = List.Transform(Text.Split(selectorRecord{0}{1}, ">"), each Text.Trim(_)),
		eachSelect = List.Accumulate(selectorList, html, (htmlstring, c) =>
			let
				selector = if Text.Contains(c, ":") then Text.BeforeDelimiter(c, ":") else c,
				hasColonSelector = Text.Contains(c, ":"),
				startTag = "<" & selector,
				endTag = "</" & selector
			in
				if (List.Last(selectorList) = c) then
					List.Transform(List.RemoveFirstN(Text.Split(htmlstring, startTag), 1), each Text.BeforeDelimiter(Text.AfterDelimiter(_, ">"), endTag))
				else
					if Text.Contains(htmlstring, startTag) then
						Text.AfterDelimiter(
							if hasColonSelector then
								if Text.Contains(c, ":nth-of-type") then
									if Text.Contains(c, ":not") then
										let
											// hacky
											nthOfTypeNumber = try Number.FromText(Text.BetweenDelimiters(Text.Replace(c, ":not(", ""), "(", ")")) otherwise 0,
											notValue = Text.BetweenDelimiters(htmlstring, startTag, endTag, if Number.IsNaN(nthOfTypeNumber) then 0 else nthOfTypeNumber - 1),
											thisValue = Text.Combine( Text.Split(Text.Replace(htmlstring, notValue, ""), startTag) )
										in
											startTag & thisValue
									else
										let
											nthOfTypeNumber = try Number.FromText(Text.BetweenDelimiters(c, "(", ")")) otherwise 0,
											notValue = Text.BetweenDelimiters(htmlstring, startTag, endTag, if Number.IsNaN(nthOfTypeNumber) then 0 else nthOfTypeNumber - 1)
										in
											startTag & notValue
								else
									Text.BetweenDelimiters(htmlstring, startTag, endTag)
							else
								Text.AfterDelimiter(Text.BeforeDelimiter(htmlstring, endTag), startTag)
						, ">")
					else
						htmlstring
			)
	in
		#table({columnHeader}, List.Transform(eachSelect, each
			let
				htmlReplacements = {
					{ "<br />", Character.FromNumber(13) },
					{ "&nbsp;", " " }
				},
				value = List.Accumulate(htmlReplacements, _, (s, c) => Text.Trim(Text.Replace(s, c{0}, c{1})))
			in
				{ value }
		));

 

View solution in original post

4 REPLIES 4
MaddogMikeB_A_G
Frequent Visitor

Did you find out wht 'Html.Table' does not exist? 

Anonymous
Not applicable

Hi!

 

No, I did not find out why and could go on without that code. 

 

BR

I looked into the power bi code (ILSpy is great 🙂 and figured out that Html.Tables is a built in function, not a Power Query function exactly.  It uses AngleSharp.net under the covers to do the css selectors ect. basically the heavy lifting of the html manipulation / searching.  

 

The following was useful for me, and could be extended to do all the html.table function - it's pretty hacky but got the job done 🙂 

 

MyHtml.Table = (html as text, selectorRecord as any, optional three as any) as any =>
	let
		columnHeader = selectorRecord{0}{0},
		selectorList = List.Transform(Text.Split(selectorRecord{0}{1}, ">"), each Text.Trim(_)),
		eachSelect = List.Accumulate(selectorList, html, (htmlstring, c) =>
			let
				selector = if Text.Contains(c, ":") then Text.BeforeDelimiter(c, ":") else c,
				hasColonSelector = Text.Contains(c, ":"),
				startTag = "<" & selector,
				endTag = "</" & selector
			in
				if (List.Last(selectorList) = c) then
					List.Transform(List.RemoveFirstN(Text.Split(htmlstring, startTag), 1), each Text.BeforeDelimiter(Text.AfterDelimiter(_, ">"), endTag))
				else
					if Text.Contains(htmlstring, startTag) then
						Text.AfterDelimiter(
							if hasColonSelector then
								if Text.Contains(c, ":nth-of-type") then
									if Text.Contains(c, ":not") then
										let
											// hacky
											nthOfTypeNumber = try Number.FromText(Text.BetweenDelimiters(Text.Replace(c, ":not(", ""), "(", ")")) otherwise 0,
											notValue = Text.BetweenDelimiters(htmlstring, startTag, endTag, if Number.IsNaN(nthOfTypeNumber) then 0 else nthOfTypeNumber - 1),
											thisValue = Text.Combine( Text.Split(Text.Replace(htmlstring, notValue, ""), startTag) )
										in
											startTag & thisValue
									else
										let
											nthOfTypeNumber = try Number.FromText(Text.BetweenDelimiters(c, "(", ")")) otherwise 0,
											notValue = Text.BetweenDelimiters(htmlstring, startTag, endTag, if Number.IsNaN(nthOfTypeNumber) then 0 else nthOfTypeNumber - 1)
										in
											startTag & notValue
								else
									Text.BetweenDelimiters(htmlstring, startTag, endTag)
							else
								Text.AfterDelimiter(Text.BeforeDelimiter(htmlstring, endTag), startTag)
						, ">")
					else
						htmlstring
			)
	in
		#table({columnHeader}, List.Transform(eachSelect, each
			let
				htmlReplacements = {
					{ "<br />", Character.FromNumber(13) },
					{ "&nbsp;", " " }
				},
				value = List.Accumulate(htmlReplacements, _, (s, c) => Text.Trim(Text.Replace(s, c{0}, c{1})))
			in
				{ value }
		));

 

Anonymous
Not applicable

Awesome! Thanks for the insights! 😀

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.