Subject:empty child nodes Author:Bernard Quinn Date:14 Aug 2008 01:42 PM
How do I make it so that empty child nodes are not generated?
When I tried to go into the definitions and add min_occurs=0 I got errors telling me that it wasn't allowed (also said something about not being allowed in the root, but none of these were root level). I don't want things like <tag \> showing up.
Subject:empty child nodes Author:Minollo I. Date:14 Aug 2008 01:54 PM
If you XQuery contains:
<tag/>
...then <tag/> will be serialized in output; you can't avoid that.
Of course, you can conditionalize the creation of nodes, like:
if (string-length($node)) then $node else ()
So, for example, you could do this, and get no output:
declare function local:filterEmpty($node) {
if (string-length($node)) then $node else ()
};
local:filterEmpty(<tag/>)
BTW, just FYI as you mentioned in other posts that you are working with RDBMS connections: note that null values in the database correspond to missing tags in the generated XML, not to empty tags.
Subject:empty child nodes Author:Bernard Quinn Date:14 Aug 2008 02:43 PM
I'm confused then (not unusual), because it is for missing elements that I am getting these empty tags. E.G. - say I have three tables, one for boxes, one for colors, one for sizes. Format of all three is the same, an integer, followed by a text field. Each element in boxes can have 0 to many corresponding elements in the color and size tables, all joined together by the primary key of the boxes table (which shows up as a foreign key in the other two tables). Let's say that there are three entries in boxes {(1,"dish"),(2,"clothes"),(3,"book")}. Let's say that the color table has {(1,"red"),(1,"green")} and size has {(1,"small"),(1,"med"),(2,"small")}. Using some left joins from boxes the following info is available:
dish - red - small
dish - red - med
dish - green - small
dish - green - med
clothes - NULL - small
NULL comes from the missing corresponding entry rather than an actual table entry of (2,NULL).
The xml I would like to generate is:
<boxes>
<box>
<name>dish</name>
<color>red</color>
<color>green</color>
<size>small</size>
<size>med</size>
</box>
<box>
<name>clothes</name>
<size>small</size>
</box>
Instead, I end up with an empty node under the clothes box:
<box>
<name>clothes</name>
<color />
<size>small</size>
</box>
Subject:empty child nodes Author:Bernard Quinn Date:14 Aug 2008 03:09 PM
So I tried your solution, and it worked, very nice, thanks... now I just have to do it 80 more times and things'll be good (well, still need to figure out how to get rid of those bad characters and try out your solution on the full dump bit)...
Subject:empty child nodes Author:Bernard Quinn Date:14 Aug 2008 03:16 PM
bear in mind that the xQuery is the result of one all-nighter where I relearned how to do it at all (had tinkered a bit a year ago, but hadn't played since), and implemented it, so this one is definitely a work in progress (and also helps explain why I have so many questions).
Subject:empty child nodes Author:Minollo I. Date:14 Aug 2008 03:27 PM
OK, that explains it; you are explicitly creating the tag in your XQuery, so, even if the content is empty, it needs to be created.
So,
<Title>
{$singles1/TI/text()}
</Title>
...will create a <Title> element no matter if $singles1/TI exists or not; if you did just:
{$singles1/TI}
...TI would not be created in output if the TI column was null in that row. Of course that won't help you, because you need to change the column names to map to different tag names... so, you'll need something like the solution I described. BTW, you may simplify it to just check the node existance rather than the content length:
{
if( $singles1/FT ) then
<ForeignTitle>
{$singles1/FT/text()}
</ForeignTitle>
else
()
}