0

Using the next SQL code, running with Oracle 10:

SELECT xmlserialize
    (
    document xmlelement
        (
        "Response", xmlforest
            (
            '00' AS "ReturnCode"
            ), xmlagg
            (
            xmlelement
                (
                "Students", xmlelement
                    (
                    "Student", xmlforest
                        (
                        'Some 1' AS "Name",
                        '1' AS "Id"
                        )
                    ), xmlelement
                    (
                    "Student", xmlforest
                        (
                        'Some 2' AS "Name",
                        '2' AS "Id"
                        )
                    )                                                                           
                ) 
            )                               
        ) AS CLOB INDENT
    ) FROM dual

... I get this XML structure:

<Response>
  <ReturnCode>00</ReturnCode>
  <Students>
    <Student>
      <Name>Some 1</Name>
      <Id>1</Id>
    </Student>
    <Student>
      <Name>Some 2</Name>
      <Id>2</Id>
    </Student>
  </Students>
</Response>

... but, I want to get this one (removing the 'root' element):

  <ReturnCode>00</ReturnCode>
  <Students>
    <Student>
      <Name>Some 1</Name>
      <Id>1</Id>
    </Student>
    <Student>
      <Name>Some 2</Name>
      <Id>2</Id>
    </Student>
  </Students>

Several attemps like this didnt work. Is mandatory to have a root element?:

SELECT xmlserialize
    (
    document xmlforest
        (
        '00' AS "ReturnCode"
        ), xmlagg
        (
        xmlelement
            (
            "Students", xmlelement
                (
                "Student", xmlforest
                    (
                    'Some 1' AS "Name",
                    '1' AS "Id"
                    )
                ), xmlelement
                (
                "Student", xmlforest
                    (
                    'Some 2' AS "Name",
                    '2' AS "Id"
                    )
                )                                                                           
            ) 
        ) AS CLOB INDENT
    ) FROM dual

Any help will be appreciated. (This is just a simplification of something more complex I need to do in some project).

3 Answers 3

3

The question is why you need this? XML should be "Well Formed"
This means:
- XML documents must have a root element
- XML elements must have a closing tag
- XML tags are case sensitive
- XML elements must be properly nested
- XML attribute values must be quoted

Add extract('/*/*') and change document -> content

SELECT xmlserialize
    (
    content xmlelement
        (
        "Response", xmlforest
            (
            '00' AS "ReturnCode"
            ), xmlagg
            (
            xmlelement
                (
                "Students", xmlelement
                    (
                    "Student", xmlforest
                        (
                        'Some 1' AS "Name",
                        '1' AS "Id"
                        )
                    ), xmlelement
                    (
                    "Student", xmlforest
                        (
                        'Some 2' AS "Name",
                        '2' AS "Id"
                        )
                    )                                                                           
                ) 
            )                               
        ).extract('/*/*') AS CLOB INDENT
    ) FROM dual
Sign up to request clarification or add additional context in comments.

1 Comment

You can avoid calling extract by using xmlconcat(...) to generate a sequence of XML elements instead of wrapping them in xmlelement("Response", ...). See my response at stackoverflow.com/a/48866515/108326 for details.
0

The easiest working way i could think is to use replace. See below:

Select replace(Replace(col,'< >',''),'</ >','') 
from 
(
SELECT xmlserialize
    (
    document xmlelement
        (
         " ", xmlforest --Putting a wide space to differentiate from other tags
            (
            '00' AS "ReturnCode"
            ), xmlagg
            (
            xmlelement
                (
                "Students", xmlelement
                    (
                    "Student", xmlforest
                        (
                        'Some 1' AS "Name",
                        '1' AS "Id"
                        )
                    ), xmlelement
                    (
                    "Student", xmlforest
                        (
                        'Some 2' AS "Name",
                        '2' AS "Id"
                        )
                    )                                                                           
                ) 
            )                               
        )
    )  AS COL
  FROM dual )

Output:

<ReturnCode>00</ReturnCode>
  <Students>
    <Student>
      <Name>Some 1</Name>
      <Id>1</Id>
    </Student>
    <Student>
      <Name>Some 2</Name>
      <Id>2</Id>
    </Student>
  </Students>

DEMO

6 Comments

No need for string manipulation of XML, just use xmlserialize(content ...) instead of xmlserialize(document ...). See the other answers to this question for examples.
@markusk There is no point answering same thing. What you answered is already been answered by someone and that's why you didnot get any votes. However by downvoting my answer you invited a downvote for repeatition of same answer.
My downvote was triggered by the use of string manipulation to modify XML (replace) instead of XML operations (xmlconcat, extract).
@markusk There was no need for downvoting. I just showed another way. As i hope you understand removing root anyways destroys the xml structure. Object was to just remove that and i achieved by simplest means. Its not necessary i do what you expect.
I consider string manipulation with replace to be strictly inferior, hence the downvote. Using a magic string like "wide space" (which is impossible to recognize or distinguish from normal whitespace in most user interfaces) seems hacky and harder to maintain.
|
-1

Removing the root element means you will no longer have a valid XML structure, but rather a sequence of XML structures. You could construct this by using xmlserialize(content ...) instead of xmlserialize(document ....).

SELECT xmlserialize(content xmlforest(
  '00' as "ReturnCode",
  xmlforest(
            xmlforest('Some 1' AS "Name",
                      '1' AS "Id"
                     ) AS "Student",
            xmlforest('Some 2' AS "Name",
                      '2' AS "Id"
                     ) AS "Student"
           ) AS "Students"
 ) AS CLOB INDENT)
FROM DUAL;

You could also use xmlconcat and xmlelement instead of xmlforest, if you prefer:

SELECT xmlserialize(content xmlconcat(
   xmlelement("ReturnCode", '00'),
   xmlelement("Students",
              xmlelement("Student",
                         xmlelement("Name", 'Some 1'),                                                            
                         xmlelement("Id", '1')
                        ),
              xmlelement("Student",
                         xmlelement("Name", 'Some 2'),
                         xmlelement("Id", '2')
                        ) 
             )
 ) AS CLOB INDENT)
FROM DUAL;

2 Comments

Isn't it the same what @Arkadiusz Łukasiewicz explained ..!! Why do you create repetition.
@XING My answer avoids the use of extract, and also demonstrates how to use xmlconcat.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.