12 Replies Latest reply: Feb 14, 2012 12:01 PM by tsuji RSS

    How to add all namespaces in root node of xquery transformation result?

    859404
      Hi,
      I'm using xquery Transformation in oracle service bus to transfrom output. The schema used for output transfromation has elements being imported from several schemas. so that output xml has these long tags with namespaces of repective schemas e.g.
      <rr:Get360ViewOfProductResponse      xmlns:rr="http://canaldigital.com/schema/product/CPMProductInformation/v2.0/">
      <ResponseHeader>
      <com:ResponseCode xmlns:com="http://broadcast.telenor.com/tsi/common/commonparameters_v1" >0</com:ResponseCode>
      <com:ResponseText xmlns:com="http://broadcast.telenor.com/tsi/common/commonparameters_v1" >0</com:ResponseText>
      </ResponseHeader>
      </rr:Get360ViewOfProductResponse>

      what I want to achieve is that all namespaces come once in the rootNode and all childnodes just use the repective prefixes, so that the xml size doesnt grow too large.Like below.
      <rr:Get360ViewOfProductResponse      xmlns:com="http://broadcast.telenor.com/tsi/common/commonparameters_v1" xmlns:rr="http://canaldigital.com/schema/product/CPMProductInformation/v2.0/" xmlns:pr="http://broadcast.telenor.com/tsi/common/program_v1">
      <ResponseHeader>
      <com:ResponseCode>0</com:ResponseCode>
      <com:ResponseText>0</com:ResponseText>
      </ResponseHeader>
      </rr:Get360ViewOfProductResponse>

      the difference is that ResponseCode and responseText should only use their prefix, and not complete namespace. How can i acheive this.

      Thanks in advance.

      Edited by: 856401 on Feb 9, 2012 1:53 AM
        • 1. Re: How to add all namespaces in root node of xquery transformation result?
          odie_63
          Hi,

          Could you give the XQuery you're currently using?
          • 2. Re: How to add all namespaces in root node of xquery transformation result?
            859404
            The xquery is huge. I'm pasting the part of it which maps the responseHeader shown in my example above.
            ------------------------------------------------------------------------------------------------------------------------------------------------
            (:: pragma bea:global-element-parameter parameter="$get360ViewOfProductResponse1" element="ns5:Get360ViewOfProductResponse" location="../XSD/CPMSchema_v20.xsd" ::)
            (:: pragma bea:global-element-return element="ns6:Get360ViewOfProductResponse" location="../XSD/CPMSchema_v3.xsd" ::)

            declare namespace ns2 = "http://broadcast.telenor.com/tsi/common/displayinformation_v1";
            declare namespace ns1 = "http://broadcast.telenor.com/tsi/common/commonparameters_v1";
            declare namespace ns4 = "http://broadcast.telenor.com/tsi/common/Property_v2";
            declare namespace ns3 = "http://broadcast.telenor.com/tsi/common/ProductMain_v2";
            declare namespace ns0 = "http://broadcast.telenor.com/tsi/common/condition_v1";
            declare namespace ns9 = "http://broadcast.telenor.com/tsi/common/extension_v1";
            declare namespace ns5 = "http://broadcast.telenor.com/tsi/psd/cpm/CPMSchema_v20";
            declare namespace ns6 = "http://canaldigital.com/schema/product/CPMProductInformation/v3.0/";
            declare namespace xf = "http://tempuri.org/CPM_OSB_v3/XQuery/Get360ViewOfProductResponse/";
            declare namespace ns7 = "http://broadcast.telenor.com/tsi/common/productofferingpricewithrules_v2";
            declare namespace ns8 = "http://broadcast.telenor.com/tsi/common/pricecomponent_v2";

            declare function xf:Get360ViewOfProductResponse($get360ViewOfProductResponse1 as element(ns5:Get360ViewOfProductResponse))
            as element(ns6:Get360ViewOfProductResponse) {
            <ns6:Get360ViewOfProductResponse>
            <ResponseHeader>
            <ns1:ResponseCode>0</ns1:ResponseCode>
            <ns1:ResponseText>{ data($get360ViewOfProductResponse1/responseDescription) }</ns1:ResponseText>
            </ResponseHeader>

            }
            </ns6:Get360ViewOfProductResponse>
            };

            declare variable $get360ViewOfProductResponse1 as element(ns5:Get360ViewOfProductResponse) external;

            xf:Get360ViewOfProductResponse($get360ViewOfProductResponse1)
            -------------------------------------------------------------------------------------------------------------------------------------------------------------------
            • 3. Re: How to add all namespaces in root node of xquery transformation result?
              tsuji
              You could use copy-namespaces setter to determine namespace preservation (of unused) and inheritance. However, in the worst scenario, if what in-scope namespaces used in the function is no where declared in its ancestors (looks like so with your excerpt, but it is most probably not in your real situation of much involved document and xquery) or in the document root itself, I don't think then you can avoid it being declared for the first time in a child element. However, with the setter copy-namespace setting inherit, its descendants at least can spare the misfortune to have to redeclare it again.
              declare copy-namespaces preserve, inherit;
              • 4. Re: How to add all namespaces in root node of xquery transformation result?
                859404
                Hi,
                Can you please show me how to use copy-namespaces in my current xquery transformation file (pasted earlier). when i simple put it in the top section where namespaces are declared, i get syntax error.

                Thanks.

                Edited by: 856401 on Feb 10, 2012 1:21 AM
                • 5. Re: How to add all namespaces in root node of xquery transformation result?
                  tsuji
                  You simply put it in the prolog as you do with declare namespace etc... Just add one more line of declare copy-namespaces of syntax as shown above already.
                  • 6. Re: How to add all namespaces in root node of xquery transformation result?
                    859404
                    I get error 'Invalid expression- Unexpected token copy-namespaces'. Is it supported by xquery version 1.0 ? Following is the updated xquery transformation which gives static error:
                    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
                    xquery version "1.0" encoding "Cp1252";
                    (:: pragma bea:global-element-parameter parameter="$get360ViewOfProductResponse1" element="ns5:Get360ViewOfProductResponse" location="../XSD/CPMSchema_v20.xsd" ::)
                    (:: pragma bea:global-element-return element="ns6:Get360ViewOfProductResponse" location="../XSD/CPMSchema_v3.xsd" ::)

                    declare namespace ns2 = "http://broadcast.telenor.com/tsi/common/displayinformation_v1";
                    declare namespace ns1 = "http://broadcast.telenor.com/tsi/common/commonparameters_v1";
                    declare namespace ns4 = "http://broadcast.telenor.com/tsi/common/Property_v2";
                    declare namespace ns3 = "http://broadcast.telenor.com/tsi/common/ProductMain_v2";
                    declare namespace ns0 = "http://broadcast.telenor.com/tsi/common/condition_v1";
                    declare namespace ns9 = "http://broadcast.telenor.com/tsi/common/extension_v1";
                    declare namespace ns5 = "http://broadcast.telenor.com/tsi/psd/cpm/CPMSchema_v20";
                    declare namespace ns6 = "http://canaldigital.com/schema/product/CPMProductInformation/v3.0/";
                    declare namespace xf = "http://tempuri.org/CPM_OSB_v3/XQuery/Get360ViewOfProductResponse/";
                    declare namespace ns7 = "http://broadcast.telenor.com/tsi/common/productofferingpricewithrules_v2";
                    declare namespace ns8 = "http://broadcast.telenor.com/tsi/common/pricecomponent_v2";
                    declare copy-namespaces preserve, inherit;

                    declare function xf:Get360ViewOfProductResponse($get360ViewOfProductResponse1 as element(ns5:Get360ViewOfProductResponse))
                    as element(ns6:Get360ViewOfProductResponse) {
                    <ns6:Get360ViewOfProductResponse>
                    <ResponseHeader>
                    <ns1:ResponseCode>0</ns1:ResponseCode>
                    <ns1:ResponseText>{ data($get360ViewOfProductResponse1/responseDescription) }</ns1:ResponseText>
                    </ResponseHeader>
                    }
                    </ns6:Get360ViewOfProductResponse>
                    };

                    declare variable $get360ViewOfProductResponse1 as element(ns5:Get360ViewOfProductResponse) external;

                    xf:Get360ViewOfProductResponse($get360ViewOfProductResponse1)
                    • 7. Re: How to add all namespaces in root node of xquery transformation result?
                      tsuji
                      Make sure copy-namespaces goes before any variable declarations. And then, as far as I know, it should be supported at least since around the time of 2007/8.

                      Whether the copy-namespaces mode default to what is not restraint by the recommendation. It is very much implementation dependent.

                      From the look of your xquery script, if you know beforehand which namespaces are going to be imported or elements retrieved, try put up all the namespace declarations in root construction appeared inside the function. I mean this.
                      declare function xf:Get360ViewOfProductResponse($get360ViewOfProductResponse1 as element(ns5:Get360ViewOfProductResponse))
                      as element(ns6:Get360ViewOfProductResponse) {
                      <ns6:Get360ViewOfProductResponse
                          xmlns:ns0="http://broadcast.telenor.com/tsi/common/condition_v1"
                          xmlns:ns1="http://broadcast.telenor.com/tsi/common/commonparameters_v1"
                          xmlns:ns2="http://broadcast.telenor.com/tsi/common/displayinformation_v1"
                          xmlns:ns3="http://broadcast.telenor.com/tsi/common/ProductMain_v2"
                          xmlns:ns4="http://broadcast.telenor.com/tsi/common/Property_v2"
                          xmlns:ns5="http://broadcast.telenor.com/tsi/psd/cpm/CPMSchema_v20"
                          xmlns:ns6="http://canaldigital.com/schema/product/CPMProductInformation/v3.0/"
                          xmlns:ns7="http://broadcast.telenor.com/tsi/common/productofferingpricewithrules_v2"
                          xmlns:ns8="http://broadcast.telenor.com/tsi/common/pricecomponent_v2"
                          xmlns:ns9="http://broadcast.telenor.com/tsi/common/extension_v1">
                      <ResponseHeader>
                      <ns1:ResponseCode>0</ns1:ResponseCode>
                      <ns1:ResponseText>{ data($get360ViewOfProductResponse1/responseDescription) }</ns1:ResponseText>
                      </ResponseHeader>
                      }
                      </ns6:Get360ViewOfProductResponse>
                      };
                      If the default mode plays to your favour, that would draw out tags without repetitive declarations of the recognized in-scope namespace.
                      • 8. Re: How to add all namespaces in root node of xquery transformation result?
                        859404
                        Thanks, this is helping. I am not getting the long namespaces in output now , although the transformation files give me warning:
                        "xml attribute does not match the target schema" which makes me feel it is not recommended practice.OR is it?
                        • 9. Re: How to add all namespaces in root node of xquery transformation result?
                          tsuji
                          +"xml attribute does not match the target schema"+
                          I would more incline to check whether the source/resultant xml document conforms to intended schemas (imported, included...) due to typos or of error more anchored to design. The practice is very legitime: one way or another those namespaces would be declared with the help of the engine or by the author exercing more control over.
                          • 10. Re: How to add all namespaces in root node of xquery transformation result?
                            859404
                            Thanks. As long as it serves the purpose, and passes validation, I am ok.
                            • 11. Re: How to add all namespaces in root node of xquery transformation result?
                              user10644361
                              Hi,

                              where exactly did you put the declaration?
                              I have the same issue and tried to put it just after the pragma but iI still get the 'Invalid expression- Unexpected token' error.

                              Thanks in advance
                              • 12. Re: How to add all namespaces in root node of xquery transformation result?
                                tsuji
                                I've checked the documentation. db 11g2 sql xml supports only copy-namespaces preserve and inherit (which is usually the desired for behaviour in common scenario). You can find it here:

                                http://docs.oracle.com/cd/E11882_01/appdev.112/e23094/xdb_xquery.htm (it is in chapter 5)

                                So maybe that's the cause. So it could not be used in xmlquery... in the context of xml db. (So full support of xquery 1.0 is not that "full" after-all: my bad.) In other implementation, like saxon, it is supported much earlier. In any case, to disentangle the history of supports is becoming calling for a great effort and quite untrackable. If I cause any confusion, I feel sorry.

                                But, at the end, a declaration of namespace needs to happen one way or another if that namespace has not been declared in the scope. Again, returning to the conditional that if the author of the query has enough info at hand, declaring it at his/her desired parent is always a viable thing to do.