XML query issue

  • Currently we have an xml stored like this

    <FlrBuild xmlns="http://tempuri.org/Floor.xsd">

    <DesignStatusFg>3</DesignStatusFg>

    </FlrBuild>

    When I try and query the xml using the following I can't see the attribute design status fg

    DECLARE @xmlComponentItemScrub XML

    SELECT @xmlComponentItemScrub = '

    <FlrBuild xmlns="http://tempuri.org/Floor.xsd">

    <DesignStatusFg>3</DesignStatusFg>

    </FlrBuild>'

    -- Check if the DesignStatusFg setting already exists

    IF EXISTS (SELECT * FROM @xmlComponentItemScrub.nodes('/FlrBuild/DesignStatusFg') n(temp))

    BEGIN

    Print 'We found it!'

    END

    IF @xmlComponentItemScrub.exist('(/FlrBuild/DesignStatusFg)[1]')='1'

    BEGIN

    Print 'We found it again!'

    END

    When I add xsd to the schema I can then query it and find the attribute I am looking for

    DECLARE @xmlComponentItemScrub XML

    SELECT @xmlComponentItemScrub = '

    <FlrBuild xmlns:xsd="http://tempuri.org/Floor.xsd">

    <DesignStatusFg>3</DesignStatusFg>

    </FlrBuild>'

    -- Check if the DesignStatusFg setting already exists

    IF EXISTS (SELECT * FROM @xmlComponentItemScrub.nodes('/FlrBuild/DesignStatusFg') n(temp))

    BEGIN

    Print 'We found it!'

    END

    IF @xmlComponentItemScrub.exist('(/FlrBuild/DesignStatusFg)[1]')='1'

    BEGIN

    Print 'We found it again!'

    END

    The second query works and finds the attribute using both methods I know of. Why is it that when I add xsd I can then query the attributes? Should I recommend to development that for all xml stored in the DB we should have a standard which requires XSD?

  • When the namespace in the xml is the default namespace as in yours (there is no :prefix in the declaration), then all elements are part of that default namespace and a "WITH XMLNAMESPACES" syntax is required to access the nodes in the xml.

    Unfortunately, AFAIK, there is no way to use "WITH XMLNAMESPACES" in an "IF" statement, so you can't access the nodes.

    <!-- default namespace declared -->

    <FlrBuild xmlns="http://tempuri.org/Floor.xsd">

    <DesignStatusFg>3</DesignStatusFg>

    </FlrBuild>'

    However, by adding a prefix to the namespace, such as "xsd" (it could be "a", "b", "foo", "bar" it doesn't matter) , you take your non-prefixed nodes out of any declared namespace and can now access them without needing to use "WITH XMLNAMESPACE" (as they are not in any declared namespace).

    <FlrBuild xmlns:xsd="http://tempuri.org/Floor.xsd">

    <DesignStatusFg>3</DesignStatusFg>

    </FlrBuild>'

    So, as to your question about developers standards, it seems like yes it might be wise not to use a plain "default" namespace if you have the choice, unless you want to work around the problem like this:

    DECLARE @xmlComponentItemScrub XML;

    SELECT @xmlComponentItemScrub = '

    <FlrBuild xmlns="http://tempuri.org/Floor.xsd">

    <DesignStatusFg>3</DesignStatusFg>

    </FlrBuild>';

    -- Check if the DesignStatusFg setting already exists

    DECLARE @count int;

    WITH XMLNAMESPACES (DEFAULT 'http://tempuri.org/Floor.xsd')

    SELECT @count=count(*)

    FROM @xmlComponentItemScrub.nodes('/FlrBuild/DesignStatusFg') AS n(temp);

    IF @count>0

    BEGIN

    Print 'We found it!';

    END;

    WITH XMLNAMESPACES (DEFAULT 'http://tempuri.org/Floor.xsd')

    SELECT @count = @xmlComponentItemScrub.exist('(/FlrBuild/DesignStatusFg)[1]');

    IF @count = 1

    BEGIN

    Print 'We found it again!';

    END;

    MM



    select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);

  • Forum Etiquette: How to post Reporting Services problems
  • [/url]
  • Forum Etiquette: How to post data/code on a forum to get the best help - by Jeff Moden
  • [/url]
  • How to Post Performance Problems - by Gail Shaw
  • [/url]

  • In the block above what does the WITH do? Is it creating a work table or something? Is there a cost to having the with statement. The example I have given is a simple one for the post. This table that I am working with has one xml column that stores three different xml schemas for my region. They have about 30 attributes in each. Each region can then put whatever schema they want in that column. I would like it if we can query this column as fields potentially for reporting. I am wondering if the with would cause a loop.

  • http://technet.microsoft.com/en-us/library/ms177607.aspx

    It is just a declaration of the namespace. Nothing to do with tables, loops or ctes.

    MM



    select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);

  • Forum Etiquette: How to post Reporting Services problems
  • [/url]
  • Forum Etiquette: How to post data/code on a forum to get the best help - by Jeff Moden
  • [/url]
  • How to Post Performance Problems - by Gail Shaw
  • [/url]

  • I am now running into the next issue. I would like to modify an attribute within the xml. I was looking online and since we are treating this as a table I am not sure what the syntax is for updating the variable

    WITH XMLNAMESPACES (DEFAULT 'http://tempuri.org/Floor.xsd')

    SET @xmlComponentItemScrub.modify('replace value of (/FlrBuild/DesignStatusFg/text())[1] with "0"')

    Can a variable be updated somehow?

  • Yes, but you are going to keep finding these little annoyances working with XML data types in SQL.

    I would highly recommend doing this sort of processing in .Net or some other programming language if you can.

    That said, here is your "modify" in a working state.

    SET @xmlComponentItemScrub.modify('

    declare default element namespace "http://tempuri.org/Floor.xsd";

    replace value of (/FlrBuild/DesignStatusFg[1]/text())[1] with 0')

    MM



    select geometry::STGeomFromWKB(0x0106000000020000000103000000010000000B0000001000000000000840000000000000003DD8CCCCCCCCCC0840000000000000003DD8CCCCCCCCCC08408014AE47E17AFC3F040000000000104000CDCCCCCCCCEC3F9C999999999913408014AE47E17AFC3F9C99999999991340000000000000003D0000000000001440000000000000003D000000000000144000000000000000400400000000001040000000000000F03F100000000000084000000000000000401000000000000840000000000000003D0103000000010000000B000000000000000000143D000000000000003D009E99999999B93F000000000000003D009E99999999B93F8014AE47E17AFC3F400000000000F03F00CDCCCCCCCCEC3FA06666666666FE3F8014AE47E17AFC3FA06666666666FE3F000000000000003D1800000000000040000000000000003D18000000000000400000000000000040400000000000F03F000000000000F03F000000000000143D0000000000000040000000000000143D000000000000003D, 0);

  • Forum Etiquette: How to post Reporting Services problems
  • [/url]
  • Forum Etiquette: How to post data/code on a forum to get the best help - by Jeff Moden
  • [/url]
  • How to Post Performance Problems - by Gail Shaw
  • [/url]

  • Thanks for the quick reply. I agree XML is difficult to navigate through. I was looking at the loop and time this would take and decided to go another direction. I converted the xml to a string and did a replace. That seems to work significantly faster than variables in this case. I am going to suggest that we change to requiring a namespace for simplicity. Thanks for all the help.

  • Viewing 7 posts - 1 through 6 (of 6 total)

    You must be logged in to reply to this topic. Login to reply