3

I want to generate an XML element using Oracle's XML documentation generation support features that looks like this

<Example Attr=""></Example>

Attr is an attribute of element Example and has a value of empty string "".

When I tried to generate an XML Element using Oracle's XML functions, I couldn't generate an XML element which has an attribute whose value is an empty string.

select XMLELEMENT("hello", xmlattributes('' as  "Max"))  from  dual

The result of the above query is

<hello></hello>

Note: there is no space between the single quotes for Max attribute.

However my requirement is

<hello Max=""></hello>     -- there is no space between the double quotes.

Is there a way to do this?

4 Answers 4

4

As you're aware, for XMLAtttribute "if the value_expr is null, then no attribute is created for that value expression".

You can work around this with InsertChildXML but it isn't terribly pretty:

select insertchildxml(xmlelement("hello"), '/hello', '@Max', null) from dual;

INSERTCHILDXML(XMLELEMENT("HELLO"),'/HELLO','@MAX',NULL)                       
--------------------------------------------------------------------------------
<hello Max=""/>

... and as you can see it collapses an empty node, but that's only a potentially issue if you want this to look exactly as you showed - it's valid XML still. There is an even uglier way around that if you really need to.

That also suggests an alternative to @smnbbrv's replace:

select updatexml(xmlelement("hello", xmlattributes('$$IMPOSSIBLE-VALUE$$' as  "Max")),
  '/hello[@Max="$$IMPOSSIBLE-VALUE$$"]/@Max', null) from dual;

UPDATEXML(XMLELEMENT("HELLO",XMLATTRIBUTES('$$IMPOSSIBLE-VALUE$$'AS"MAX")),'/HEL
--------------------------------------------------------------------------------
<hello Max=""/>

which might be easier if your max attribute value is coming from data as you can NVL it to the impossible value. I'm not a fan of using magic values though really.

Sign up to request clarification or add additional context in comments.

7 Comments

@user445, if this solves your problem, you should mark this as accepted. Everybody will know, that this issue is done and Alex is happy with some reputation points. Thx!
@Shnugo. Accepted! Thank you :)
@Shnugo this is a bit unfair to apply pressure on the people by pushing your opinion. You should have posted this as a comment on a question and not on an answer
You don't need to publicly justify your choice; but follow the help center guidance and choose the best solution to your problem (or wait for other answers; there may still be other ways to do this). 'Best' is subjective of course, but that's partly the point, it's up to you - don't be pressured to accept or even upvote an answer (even mine!)
@smnbbrv, you are right. Actually when I wrote this I hadn't seen, that user445 commented your answer with the same "solves my problem". I'm one of your upvoters anyway :-)
|
3

What about setting the property value to some impossible value and then replace it with the value you need (so, empty string in your case)?

select replace(
  XMLELEMENT("hello", xmlattributes('$$IMPOSSIBLE-VALUE$$' as  "Max")).getStringVal(),
  '$$IMPOSSIBLE-VALUE$$'
)
from  dual;

I assume you anyway in the end need the string value, so even if this XMLELEMENT is just an example of the problem and you have a biiiig XML generated, you still can generate it first and then, finally, replace all the values with one command as shown above.

Comments

0

I'm using this approach (you write the source attribute instead of the "null"). This way, you don't have to search for some overall impossible value, it's enough to be impossible for that attribute.

select replace(XMLELEMENT("hello", xmlattributes(nvl(null,' ') as "Max")).getstringval(), 'Max=" "', 'Max=""') from dual

Comments

0

I used updatexml() similar to A. Poole's example to create an empty string

set serveroutput on
 DECLARE
   xa xmltype;
   xb xmltype;
 BEGIN
   xa  := xmltype('<surfbreaks>'||
     '<break lineNum="0" recordtype="empty">d street </break>'||
     '<break lineNum="0" recordtype="empty">recordtype="empty" </break>'||
     '</surfbreaks>');

  dbms_output.put_line ('Before:');
  dbms_output.put_line (xa.getclobval);

  select UPDATEXML(xa, '//@recordtype', '') into xb from dual;
  dbms_output.put_line ('After:');
  dbms_output.put_line (xb.getclobval);
END; /

Comments

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.