easy question - empty element?

Discussion in 'XML' started by Valery, Oct 30, 2007.

  1. Valery

    Valery Guest

    In the following XML:

    <?xml version="1.0" encoding="utf-8" ?>
    <Plcy service="ILiability" boId ="LifePolicy, 1">
    <Prem service="IPremium" boId ="RegularPremium, 1"></Prem>
    <L1 service="ILifeMain" type = "Life1">
    <FirstName>Sheila</FirstName>
    <Age>65</Age>
    <Relation>spouse</Relation>
    </L1>
    <L2 service="ILife" type = "Life2">
    <FirstName>Bruce</FirstName>
    <Age>70</Age>
    </L2>
    </Plcy>

    I would like to select Nodes with boId attribute which are empty. I am
    using an XPath expression:

    "//*[@boId and not(text())]"

    but MS VS XPathNavigator's Select() returns both Plcy and Prem. It
    also sets IsEmpty field of Prem node to false.

    Whose fault is it - mine or MS?

    Yours,
    Valery the Newbie
    Valery, Oct 30, 2007
    #1
    1. Advertising

  2. Valery

    Pavel Lepin Guest

    Valery <> wrote in
    <>:
    > <?xml version="1.0" encoding="utf-8" ?>
    > <Plcy service="ILiability" boId ="LifePolicy, 1">
    > <Prem service="IPremium" boId ="RegularPremium,
    > 1"></Prem> <L1 service="ILifeMain" type = "Life1">
    > <FirstName>Sheila</FirstName>
    > <Age>65</Age>
    > <Relation>spouse</Relation>
    > </L1>
    > <L2 service="ILife" type = "Life2">
    > <FirstName>Bruce</FirstName>
    > <Age>70</Age>
    > </L2>
    > </Plcy>
    >
    > I would like to select Nodes with boId attribute which are
    > empty. I am using an XPath expression:
    >
    > "//*[@boId and not(text())]"


    The default axis is child::, therefore this doesn't
    mean 'are empty' but 'have no text node children' instead.

    > but MS VS XPathNavigator's Select() returns both Plcy and
    > Prem.


    Actually, your Plcy element does have text node children.
    Either you're quietly normalising whitespace somewhere (and
    failed to mention it to us for some reason) or you're
    posting beautified XML instead of the original document
    (and failed to mention it), OR MSXML's XPath evaluator is
    seriously borken, which I find a bit hard to believe.

    > It also sets IsEmpty field of Prem node to false.


    Er, what? I can't seem to find any mention of isEmpty
    property or method in DOM specs.

    > Whose fault is it - mine or MS?


    The data is insufficient, so it's hard to tell, but I'd
    guess it's yours.

    Depending on what you mean by 'empty', you might actually
    want one of the following:

    //*[@boId and not(descendant::text())]
    //*[@boId and not(node())]
    //*[@boId and not(text()[normalize-space()])]
    //*[@boId and not(descendant::text()[normalize-space()])]

    --
    It is rare to find learned men who are clean, do not stink,
    and have a sense of humour. -- Liselotte in a letter to
    Sophie, 30 Jul 1705
    Pavel Lepin, Oct 30, 2007
    #2
    1. Advertising

  3. Valery wrote:

    > I would like to select Nodes with boId attribute which are empty. I am
    > using an XPath expression:
    >
    > "//*[@boId and not(text())]"
    >
    > but MS VS XPathNavigator's Select() returns both Plcy and Prem. It
    > also sets IsEmpty field of Prem node to false.
    >
    > Whose fault is it - mine or MS?


    As for the IsEmpty property, it is documented here:
    <URL:http://msdn2.microsoft.com/en-us/library/System.Xml.XmlElement.IsEmpty.aspx>.
    It does not check whether an element has no child nodes, rather it
    checks (or sets) whether an element is serialized as <element/> or
    <element></element>, for the former case it is true, for the latter it
    is false. In your example you have
    <Prem service="IPremium" boId ="RegularPremium, 1"></Prem>
    so the property is false. It would be true for
    <Prem service="IPremium" boId ="RegularPremium, 1"/>
    As for the white space problem, you can set the property
    PreserveWhitespace on XmlDocument
    <URL:http://msdn2.microsoft.com/en-us/library/System.Xml.XmlDocument.PreserveWhitespace.aspx>
    before you load. By default it is false, set it to true for your needs.




    --

    Martin Honnen
    http://JavaScript.FAQTs.com/
    Martin Honnen, Oct 30, 2007
    #3
  4. Valery

    Andy Dingley Guest

    On 30 Oct, 08:53, Pavel Lepin <> wrote:

    > Depending on what you mean by 'empty', you might actually
    > want one of the following:
    >
    > //*[@boId and not(descendant::text())]
    > //*[@boId and not(node())]
    > //*[@boId and not(text()[normalize-space()])]
    > //*[@boId and not(descendant::text()[normalize-space()])]


    I can't imagine many situations where "//*[...]" is a good idea,
    especially not for an XPath newbie. That's going to match every
    element in the tree, depending only on a complex predicate to filter
    them. Predicates aren't easy to get right when you're starting out!

    As you usually know the element name you're trying to match, it's
    often going to be easier to match on the <policy> or <premium>
    elements with "policy [...]" or "premium [...]" and a simpler and more
    reliable predicate.

    I'd also advise using "policy [...]" rather than "//policy [...]",
    unless you really need to. That "//" operation can be a nuisance too.

    I'd also strongly recommend a more readable element named "<policy>"
    rather than "<Plcy>". Abbreviating these names and introducing mixed-
    case is just setting yourself up to make maintenance awkward in the
    future and there's no benefit to doing it.
    Andy Dingley, Oct 30, 2007
    #4
  5. Valery

    Pavel Lepin Guest

    Martin Honnen <> wrote in
    <472720be$0$16669$-online.net>:
    > Valery wrote:
    >> I would like to select Nodes with boId attribute which
    >> are empty. I am using an XPath expression:
    >>
    >> "//*[@boId and not(text())]"
    >>
    >> but MS VS XPathNavigator's Select() returns both Plcy and
    >> Prem. It also sets IsEmpty field of Prem node to false.

    >
    > As for the IsEmpty property, it is documented here:


    [long-ish url snipped]

    Oh my goodness! It's a serialisation property that actually
    messes with the document structure when manually set to
    true?!

    Returns true if the element is to be serialized in the
    short tag format "<item/>"; false for the long
    format "<item></item>". When setting this property, if set
    to true, the children of the element are removed and the
    element is serialized in the short tag format.

    This is SO brain-damaged.

    --
    It is rare to find learned men who are clean, do not stink,
    and have a sense of humour. -- Liselotte in a letter to
    Sophie, 30 Jul 1705
    Pavel Lepin, Oct 30, 2007
    #5
  6. Valery

    Pavel Lepin Guest

    Andy Dingley <> wrote in
    <>:
    > On 30 Oct, 08:53, Pavel Lepin <> wrote:
    >> Depending on what you mean by 'empty', you might actually
    >> want one of the following:
    >>
    >> //*[@boId and not(descendant::text())]
    >> //*[@boId and not(node())]
    >> //*[@boId and not(text()[normalize-space()])]
    >> //*[@boId and
    >> not(descendant::text()[normalize-space()])]

    >
    > I can't imagine many situations where "//*[...]" is a good
    > idea, especially not for an XPath newbie.


    There certainly are some. Processing meta-data stored in
    attributes from a dedicated namespace seems to be one of
    the more common use cases.

    > That's going to match every element in the tree, depending
    > only on a complex predicate to filter them.


    Them's the breaks.

    > As you usually know the element name you're trying to
    > match...


    Usually, but not necessarily.

    > I'd also strongly recommend a more readable element named
    > "<policy>" rather than "<Plcy>".


    Agreed in principle, but in this case it took me all of a
    quarter a second to parse 'Plcy'.

    --
    It is rare to find learned men who are clean, do not stink,
    and have a sense of humour. -- Liselotte in a letter to
    Sophie, 30 Jul 1705
    Pavel Lepin, Oct 30, 2007
    #6
  7. Valery

    Andy Dingley Guest

    On Tue, 30 Oct 2007 13:16:49 +0100, Martin Honnen <>
    wrote:

    >It does not check whether an element has no child nodes, rather it
    >checks (or sets) whether an element is serialized as <element/> or
    ><element></element>, for the former case it is true, for the latter it
    >is false.


    Ooh, nice ! A pseudo-DOM property that's tightly coupled to a minor
    detail of serialization: that some child nodes (elements and text)
    appear in one place, whilst other child nodes (attributes) don't.

    What on earth is this thing _for_, and when is it ever going to be a
    good idea to actually use the damned thing? Sometimes I wonder what
    they're smoking in Redmond
    Andy Dingley, Oct 30, 2007
    #7
  8. Valery

    Andy Dingley Guest

    On 30 Oct, 14:24, Pavel Lepin <> wrote:

    > > I can't imagine many situations where "//*[...]" is a good
    > > idea, especially not for an XPath newbie.

    >
    > There certainly are some. Processing meta-data stored in
    > attributes from a dedicated namespace seems to be one of
    > the more common use cases.


    Even in that case, you're likely to know the attribute name you're
    after - it's the same situation I describe, just with attributes
    rather than elements.

    Now there are admittedly many cases when you do want to apply a less
    procedural and more declarative coding style to XSLT, as this is good
    practice in many cases (usually where you don't know the document
    structure beforehand). This is a tricky technique though, not newbie
    stuff.

    > > I'd also strongly recommend a more readable element named
    > > "<policy>" rather than "<Plcy>".

    >
    > Agreed in principle, but in this case it took me all of a
    > quarter a second to parse 'Plcy'.


    I can't afford a quarter of a second. I've got a DB schema here that's
    3-4 thousand lines long XML document. Now I know that the _computers_
    can make sense of it all and can tie the column entities to the type
    and purpose information, but I as a human can't. I need help from
    naming conventions. Repeat this over the thousands of instances in a
    typical system and all those quarter seconds add up.
    Andy Dingley, Oct 31, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hazzard
    Replies:
    2
    Views:
    633
    Hazzard
    Apr 6, 2004
  2. John

    empty/non-empty element

    John, Jul 15, 2003, in forum: XML
    Replies:
    1
    Views:
    1,023
    Klaus Johannes Rusch
    Jul 16, 2003
  3. Lukas
    Replies:
    3
    Views:
    803
    spiff
    Nov 10, 2005
  4. Bruno Desthuilliers
    Replies:
    5
    Views:
    380
    Bruno Desthuilliers
    Aug 29, 2007
  5. HANM
    Replies:
    2
    Views:
    706
    Joseph Kesselman
    Jan 29, 2008
Loading...

Share This Page