<div dir="ltr">Hi Mark,<div><br></div><div>thanks for the answer. It works. I do not understand how could I overlook compileType. Notice it earlier could have saved me from tens of XPaths.</div><div><br></div><div>There is only one minor problem. The element with xsi:Type can be defined in the schema either as xs:anyType or as a base type. So I decided to use replace hook and for each element to check xsi:type first. If there is a xsi:type I will create new reader, otherwise I use the reader passed to the hook. But if I create a new reader and call it from the hook, the hook is called again, again, and again. So I need to come up with a cumbersome solution how to skip the invocation of reader based on xsi:type when I am already in the reader based on xsi:type.</div><div><br></div><div>Is there a cleaner way how to deal with such infinite recursion?</div><div><br></div><div>Also if I use reader instead of compile, compileType I will end up with error message: cannot find element or attribute `{urn:testHook}extType&#39; at me:extType<br></div><div><br></div><div>Both problems are better illustrated with example below:</div><div><br></div><div>Thanks </div><div><br></div><div>Roman Daniel </div><div><br></div><div><div>use strict;</div><div>use warnings;</div><div><br></div><div>use XML::Compile::Schema;</div><div>use XML::Compile::Util qw(pack_type);</div><div>use Data::Dump qw(pp);</div><div><br></div><div>sub get_xsi_type {</div><div>    my ($elem) = @_;</div><div><br></div><div>    my $type</div><div>        = $elem-&gt;getAttributeNS( &quot;<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>&quot;,</div><div>        &#39;type&#39; )</div><div>        or return;</div><div><br></div><div>    my ( $prefix, $localname )</div><div>        = $type =~ /^(.*?):(.*)/ ? ( $1, $2 ) : ( &#39;&#39;, $type );</div><div>    my $ns = $elem-&gt;lookupNamespaceURI($prefix);</div><div>    return pack_type( $ns, $localname );</div><div>}</div><div><br></div><div>my $TEST_NS    = &#39;urn:testHook&#39;;</div><div>my $schema_txt = &lt;&lt;&quot;END_SCHEMA&quot;;</div><div>&lt;schema targetNamespace=&quot;$TEST_NS&quot;</div><div>        xmlns=&quot;<a href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema</a>&quot;</div><div><span class="" style="white-space:pre">        </span>xmlns:me=&quot;$TEST_NS&quot;</div><div><span class="" style="white-space:pre">        </span>elementFormDefault=&quot;qualified&quot;&gt;</div><div><br></div><div>&lt;element name=&quot;env&quot;&gt;</div><div>  &lt;complexType&gt;</div><div>    &lt;sequence&gt;</div><div>       &lt;element name=&quot;alfa&quot; type=&quot;me:baseType&quot; /&gt;</div><div>       &lt;element name=&quot;beta&quot; type=&quot;anyType&quot;  /&gt;</div><div>    &lt;/sequence&gt;</div><div>  &lt;/complexType&gt;</div><div>&lt;/element&gt;</div><div><br></div><div>&lt;complexType name=&quot;baseType&quot;&gt;</div><div>    &lt;sequence&gt;</div><div>        &lt;element name=&quot;num_one&quot; type=&quot;int&quot; /&gt;</div><div>    &lt;/sequence&gt;</div><div>&lt;/complexType&gt;</div><div><br></div><div>&lt;complexType name=&quot;extType&quot;&gt;</div><div>  &lt;complexContent&gt;</div><div>      &lt;extension base=&quot;me:baseType&quot;&gt;</div><div>      &lt;sequence&gt;</div><div>        &lt;element name=&quot;num_two&quot; type=&quot;int&quot; /&gt;</div><div>      &lt;/sequence&gt;</div><div>      &lt;/extension&gt;</div><div>  &lt;/complexContent&gt;</div><div>&lt;/complexType&gt;</div><div><br></div><div>&lt;/schema&gt;</div><div>END_SCHEMA</div><div><br></div><div>my $xc = XML::Compile::Schema-&gt;new( $schema_txt, allow_undeclared =&gt; 1 );</div><div><br></div><div><br></div><div>my $skip_elem;</div><div>my $hook_ok = sub {</div><div>    my ( $elem, $args, $path, $type, $r ) = @_;</div><div><br></div><div>    if ( not($skip_elem) and my $xsi_type = get_xsi_type($elem) ) {</div><div>        my $type_reader = $xc-&gt;compileType(</div><div>            READER  =&gt; $xsi_type,</div><div>            element =&gt; pack_type( $elem-&gt;namespaceURI, $elem-&gt;localname ),</div><div>        );</div><div>        $skip_elem = 1;</div><div>        return $type_reader-&gt;($elem);</div><div>    }</div><div>    undef $skip_elem;</div><div>    return $r-&gt;($elem);</div><div>};</div><div>my $hook_infinite = sub {</div><div>    my ( $elem, $args, $path, $type, $r ) = @_;</div><div><br></div><div>    if ( my $xsi_type = get_xsi_type($elem) ) {</div><div>        my $type_reader = $xc-&gt;compileType(</div><div>            READER  =&gt; $xsi_type,</div><div>            element =&gt; pack_type( $elem-&gt;namespaceURI, $elem-&gt;localname ),</div><div>        );</div><div>        return $type_reader-&gt;($elem);</div><div>    }</div><div>    return $r-&gt;($elem);</div><div>};</div><div>$xc-&gt;addHook(</div><div>    action  =&gt; &#39;READER&#39;,</div><div>    replace =&gt; $hook_ok,</div><div>);</div><div><br></div><div>my $reader = $xc-&gt;compile( READER =&gt; pack_type( $TEST_NS, &#39;env&#39; ) );</div><div>my $doc = XML::LibXML-&gt;new-&gt;parse_string(&lt;&lt;&quot;END_XML&quot;);</div><div>&lt;me:env xmlns:me=&quot;$TEST_NS&quot; xmlns:xsi=&quot;<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>&quot;&gt;</div><div>    &lt;me:alfa xsi:type=&quot;me:extType&quot;&gt;</div><div><span class="" style="white-space:pre">        </span>&lt;me:num_one&gt;12&lt;/me:num_one&gt;</div><div><span class="" style="white-space:pre">        </span>&lt;me:num_two&gt;13&lt;/me:num_two&gt;</div><div>    &lt;/me:alfa&gt;</div><div>    &lt;me:beta xsi:type=&quot;me:extType&quot;&gt;</div><div><span class="" style="white-space:pre">        </span>&lt;me:num_one&gt;14&lt;/me:num_one&gt;</div><div><span class="" style="white-space:pre">        </span>&lt;me:num_two&gt;15&lt;/me:num_two&gt;</div><div>    &lt;/me:beta&gt;</div><div>&lt;/me:env&gt;</div><div>END_XML</div><div><br></div><div>my $struct = $reader-&gt;( $doc-&gt;documentElement );</div><div>pp($struct);</div><div><br></div></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-11-23 9:55 GMT+01:00 Mark Overmeer <span dir="ltr">&lt;<a href="mailto:mark@overmeer.net" target="_blank">mark@overmeer.net</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
Hi Roman,<br>
<br>
* Roman Daniel (<a href="mailto:roman.daniel@davosro.cz">roman.daniel@davosro.cz</a>) [151122 19:08]:<br>
<span class="">&gt; I have a schema (VMWare webservices, with urn:vim25 namespace) which have<br>
&gt; some elements defined as xsd:anyType<br>
<br>
</span><span class="">&gt;          &lt;element name=&quot;val&quot; type=&quot;xsd:anyType&quot; /&gt;<br>
</span><span class="">&gt;          &lt;val xsi:type=&quot;ManagedEntityStatus&quot;&gt;green&lt;/val&gt;<br>
<br>
</span>The ugliness of anyType combined with the ugliness of xsi:type!  Argggg!<br>
Haven&#39;t seen that before.<br>
<span class=""><br>
&gt; When I read XML elements based on such schema, those elements (val above),<br>
&gt; are left untranslated and appears in the resulting structure<br>
&gt; as original XML::LibXML elements. I understand this and do not expect<br>
&gt; XML::Compile to behave differently.<br>
<br>
</span>That&#39;s the default behavior of the anyType handler, yes.<br>
<span class=""><br>
&gt; What I want is to translate those &quot;xsd:anyType&quot; elements manually, either<br>
&gt; via hook or by traversing the result structure and compiling those<br>
&gt; untranslated elements with another call of a new reader.<br>
<br>
</span>There exists logic to decode &lt;any&gt; elements, but not for anyType elements.<br>
Yes, a hook will probably work.<br>
<span class=""><br>
&gt; Since all of these elements always come with a type I thought that would be<br>
&gt; nice to create a new reader for the type,<br>
&gt; say &quot;{urn:vim25}ManagedEntityStatus&quot;.<br>
&gt;<br>
&gt; my $reader = $xml_schema-&gt;compile(READER =&gt;<br>
&gt; &quot;{urn:vim25}ManagedEntityStatus&quot;);<br>
<br>
</span>Why are you not using<br>
    my $r = $schema-&gt;reader(&quot;{urn:vim25}ManagedEntityStatus&quot;);<br>
<br>
or  $schema-&gt;addPrefixes(vm =&gt; &#39;urn:vim25&#39;);<br>
    my $r = $schema-&gt;reader(&quot;vm:ManagedEntityStatus&quot;);<br>
<br>
It will cash the compiled handlers for you.<br>
<span class=""><br>
&gt; with the meaning read the element, translate its content and attributes<br>
&gt; according to XML type, regardless of element name.<br>
&gt; But to create such $reader is not possible.<br>
<br>
</span>Of course it is possible... whether it is supported is a different<br>
question ;-)<br>
<span class=""><br>
&gt; So the only other way I can imagine is to:<br>
&gt;<br>
&gt; 1) add a new fake XML schema to my $xml_schema<br>
&gt;<br>
&gt; &lt;xsd:schema xmlns:xsd=&quot;<a href="http://www.w3.org/2001/XMLSchema" rel="noreferrer" target="_blank">http://www.w3.org/2001/XMLSchema</a>&quot;<br>
&gt;     xmlns:tns=&quot;urn:myNonsenseSchema&quot;<br>
&gt;     xmlns:orig=&quot;urn:vim25&quot;<br>
&gt;     targetNamespace=&quot;urn:myNonsenseSchema&quot;<br>
&gt;     elementFormDefault=&quot;qualified&quot;&gt;<br>
&gt; &lt;xsd:element name=&quot;ManagedEntityStatus&quot; type=&quot;orig:ManagedEntityStatus&quot;/&gt;<br>
&gt; &lt;/xsd:element&gt;<br>
&gt;<br>
&gt; creating an element for the type.<br>
<br>
</span>This is the trick used by $schema-&gt;compileType<br>
Don&#39;t hessitate to ask for more details.<br>
<span class="HOEnZb"><font color="#888888">--<br>
Regards,<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
               MarkOv<br>
<br>
------------------------------------------------------------------------<br>
       Mark Overmeer MSc                                MARKOV Solutions<br>
       Mark@Overmeer.net                          <a href="mailto:solutions@overmeer.net">solutions@overmeer.net</a><br>
<a href="http://Mark.Overmeer.net" rel="noreferrer" target="_blank">http://Mark.Overmeer.net</a>                   <a href="http://solutions.overmeer.net" rel="noreferrer" target="_blank">http://solutions.overmeer.net</a><br>
<br>
</div></div></blockquote></div><br></div>