{"id":953,"date":"2010-01-20T15:07:00","date_gmt":"2010-01-20T15:07:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2010\/01\/20\/fun-with-dynamic-objects-doug-rothaus\/"},"modified":"2024-07-05T12:42:03","modified_gmt":"2024-07-05T19:42:03","slug":"fun-with-dynamic-objects-doug-rothaus","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/fun-with-dynamic-objects-doug-rothaus\/","title":{"rendered":"Fun With Dynamic Objects (Doug Rothaus)"},"content":{"rendered":"<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">A<\/font><\/p>\n<p><font size=\"3\" face=\"Calibri\"> while back, I remember being asked if there was a simple way to expose a source XML document as an object with properties. That is, if the root XML element had a child element <\/font><span>&lt;Name&gt;Doug&lt;\/Name&gt;<\/span><font size=\"3\" face=\"Calibri\">, then the object would have a <\/font><span>Name<\/span><font size=\"3\" face=\"Calibri\"> property that was a string and returned &ldquo;Doug&rdquo;. The catch was that the XML document did not conform to a specific schema. Hence, you could not simply create an object with a <\/font><span>Name<\/span><font size=\"3\" face=\"Calibri\"> property, because you did not know if the source document had a <\/font><span>&lt;Name&gt;<\/span><font size=\"3\" face=\"Calibri\"> element. While there are ways to expose the XML data dynamically, you couldn&rsquo;t quite do what was being asked.<\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">Enter dynamic objects in Visual Basic 2010. Now, this is possible. This means that you can use the classes in the <b>System.Dynamic<\/b> namespace to create objects that expose properties and methods dynamically at run-time and solve the original problem. In this example, we will create an object that inherits the <b>System.Dynamic.DynamicObject<\/b> class. The <b>DynamicObject<\/b> class has methods that you can override to provide code specific to your implementation. When VB performs a late-bound request on an object that implements the <b>DynamicObject<\/b> class, it calls one of the methods of the <b>DynamicObject<\/b> class to obtain the result. Consider this simple example:<\/font><\/p>\n<p class=\"MsoNormal\"><span>Imports<\/span><span> System.Dynamic<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Public<\/span><span> <span>Class<\/span> <span>SimpleObject<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Inherits<\/span> <span>DynamicObject<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Overrides<\/span> <span>Function<\/span> TryGetMember(<span>ByVal<\/span> binder <span>As<\/span> <span>GetMemberBinder<\/span>, <\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>ByRef<\/span> result <span>As<\/span> <span>Object<\/span>) <span>As<\/span> <span>Boolean<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> binder.Name = <span>&#8220;Address&#8221;<\/span> <span>Then<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>result = <span>&#8220;Value&#8221;<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> <span>True<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> <span>False<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Function<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>End<\/span><span> <span>Class<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/span>&nbsp;<\/p>\n<p class=\"MsoNormal\"><font size=\"\n3\" face=\"Calibri\">Now consider this code that creates an instance of the object and accesses properties of that instance.<\/font><\/p>\n<p class=\"MsoNormal\"><span>Module<\/span><span> <span>Module1<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Sub<\/span> Main()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> t <span>As<\/span> <span>Object<\/span> = <span>New<\/span> <span>SimpleObject<\/span>()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Console<\/span>.WriteLine(t.Address)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Console<\/span>.WriteLine(t.Street)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>End<\/span><span> <span>Module<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">First, in order to ensure that requests made of the dynamic object are late-bound, we need to type the variable as <b>Object<\/b>. Then we make two late-bound requests for object properties: <\/font><span>Address<\/span><font size=\"3\" face=\"Calibri\"> and <\/font><span>Street<\/span><font size=\"3\" face=\"Calibri\">. When you access the <\/font><span>Address<\/span><font size=\"3\" face=\"Calibri\"> property, a call is made to the <b>TryGetMember<\/b> method of the <b>DynamicObject<\/b> class, which we have overridden. The <b>GetMemberBinder<\/b> object instance that is passed to our <b>TryGetMember<\/b> method contains the name of the requested member in its <b>Name<\/b> property. Our small sample matches that name and returns the string &ldquo;Value&rdquo;. When you access the <\/font><span>Street<\/span><font size=\"3\" face=\"Calibri\"> property, a call is made to the <b>TryGetMember<\/b> method, the name does not match anything that our code supports, so the method returns <b>False<\/b>. <b>False<\/b> indicates an unsupported member, and an exception is thrown. <\/font><\/p>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">To solve our initial problem of &ldquo;hiding&rdquo; source XML and exposing an object instead, we can use the <b>DynamicObject<\/b> class in this same fashion. When a property is requested of our dynamic object, our code can search the XML source for a matching XML element name, and return the corresponding value as the property value. Let&rsquo;s look at an example.<\/font><\/p>\n<h2><font color=\"#4f81bd\" size=\"4\" face=\"Cambria\">DynamicXmlObject example<\/font><\/h2>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">Let&rsquo;s jump into the code and we&rsquo;ll talk about how the object behaves as we go. We start with a class that inherits <b>DynamicObject<\/b>. Let&rsquo;s name it <\/font><span>DynamicXmlObject<\/span><font size=\"3\" face=\"Calibri\">.<\/font><\/p>\n<p class=\"MsoNormal\"><span>Imports<\/span><span> System.Dynamic<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Public<\/span><span> <span>Class<\/span> <span>DynamicXmlObject<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Inherits<\/span> <span>DynamicObject<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>End<\/span><span> <span>Class<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<h3><font color=\"#4f81bd\" size=\"3\" face=\"Cambria\">Constructors<\/font><\/h3>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">We will add two constructors for the class. One that takes a path to an XML file as the source, and another that takes an <b>XElement<\/b>. <span>&nbsp;<\/span>The constructor that takes an <b>XElement<\/b> is not just for user convenience. We&rsquo;ll use this later when dealing with child elements that have attributes or children. Also for this class, we won&rsquo;t expose a settable property for the source XML, so we&rsquo;ll &ldquo;disable&rdquo; the empty constructor by making it <b>Protected<\/b>.<\/font><\/p>\n<p class=\"MsoNormal\"><span>Imports<\/span><span> System.Dynamic<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Imports<\/span><span> System.IO<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>Public<\/span><span> <span>Class<\/span> <span>DynamicXmlObject<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Inherits<\/span> <span>DynamicObject<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; The source XML for this instance.<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> p_Xml <span>As<\/span> <span>XElement<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Create a new DynamicXmlObject with the specified source file.<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Sub<\/span> <span>New<\/span>(<span>ByVal<\/span> filePath <span>As<\/span> <span>String<\/span>)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> <span>Not<\/span> <span>File<\/span>.Exists(filePath) <span>Then<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Throw<\/span> <span>New<\/span> <span>Exception<\/span>(<span>&#8220;File does not exist.&#8221;<\/span>)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>p_Xml = <span>XElement<\/span>.Load(filePath)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Create a new DynamicXmlObject with the specified source XElement.<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Sub<\/span> <span>New<\/span>(<span>ByVal<\/span> xml <span>As<\/span> <span>XElement<\/span>)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>p_Xml = xml<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Disable the empty constructor.<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Protected<\/span> <span>Sub<\/span> <span>New<\/span>()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span>End<\/span><span> <span>Class<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\">\n<p><font size=\"3\" face=\"Calibri\">&nbsp;<\/font><\/p>\n<\/p>\n<h3><font color=\"#4f81bd\" size=\"3\" face=\"Cambria\">Implementing GetDynamicMemberNames<\/font><\/h3>\n<p class=\"MsoNormal\"><font size=\"3\" face=\"Calibri\">This next piece of code is optional. I&rsquo;ve added it so that our object supports reflection-like functionality.<span>&nbsp; <\/span>You can expose the member names of your dynamic object using the <b>GetDynamicMemberNames<\/b> method of the <b>DynamicObject<\/b> class. Our sample object will return all of the child element names and attribute names of the current element. I&rsquo;ve added a case-insensitive <b>Distinct<\/b> comparison so that only a single name is returned if multiple entries are found. The search looks at only the <b>LocalName<\/b> property of the <b>XName<\/b> for an element or attribute. XML namespaces are ignored. That is, <\/font><span>&lt;a:Name&gt;<\/span><font size=\"3\" face=\"Calibri\"> and <\/font><span>&lt;b:Name&gt;<\/span><font size=\"3\" face=\"Calibri\"> are considered to be duplicate element names.<\/font><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Overrides<\/span> <span>Function<\/span> GetDynamicMemberNames() <span>As<\/span> <span>IEnumerable<\/span>(<span>Of<\/span> <span>String<\/span>)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> names = (<span>From<\/span> e <span>In<\/span> p_Xml.Elements() <span>Select<\/span> e.Name.LocalName).Union(<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>From<\/span> a <span>In<\/span> p_Xml.Attributes() <span>Select<\/span> a.Name.LocalName)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> (<span>From<\/span> n <span>In<\/span> names <\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&amp;nbsp<\/span><\/span><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A while back, I remember being asked if there was a simple way to expose a source XML document as an object with properties. That is, if the root XML element had a child element &lt;Name&gt;Doug&lt;\/Name&gt;, then the object would have a Name property that was a string and returned &ldquo;Doug&rdquo;. The catch was that [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[195],"tags":[59,167,185],"class_list":["post-953","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-visual-basic","tag-doug-rothaus","tag-vb2010","tag-xml"],"acf":[],"blog_post_summary":"<p>A while back, I remember being asked if there was a simple way to expose a source XML document as an object with properties. That is, if the root XML element had a child element &lt;Name&gt;Doug&lt;\/Name&gt;, then the object would have a Name property that was a string and returned &ldquo;Doug&rdquo;. The catch was that [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/953","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=953"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/953\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=953"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=953"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=953"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}