Showing posts with label xml. Show all posts
Showing posts with label xml. Show all posts

Thursday, March 29, 2012

Foreach NodeList Enumerator

Does anyone have any experience of using the NodeList enumerator in a Foreach loop? BOL is a bit light on this.

I want to enumerate over an XML Document that is passed into my package. The package is executed from a .net application.
Has anyone done anything like this?
Any demo material?
Should I pass the XML Document into an SSIS object variable or a String variable?
Can the NodeList enumerator enumerate an XML document that is stored in a String variable?
etc...
Thanks
JamieHey Jamie,
I've done this -- albeit for a rather simple example. I have an XML file that is just a persisted collection of structs with properties called "BusinessObjectName", so the data itself looks like this:
<DimensionInfos xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BusinessDimensionEntries>
<anyType xsi:type="BusinessDimensionInfo">
<BusinessObjectName>User</BusinessObjectName>
</anyType>
</BusinessDimensionEntries>
</DimensionInfos>

Essentially I want to iterate over all the nodes and pull out the "BusinessObjectName" from each. I created a foreach NodeList enumerator, document source is the file, enumeration type is NodeText, XPath source is DirectInput (meaning I specify it within the task) and the XPath string is "//BusinessObjectName". This query will recursively match all nodes of that type. Then I map index 0 to some variable and I will get the NodeText "User" (as specified) of the node(s) that match my XPath expression.
Not sure if you came across this article:
http://databasejournal.com/features/mssql/article.php/3528791
Also, a good XPath reference:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/_xpath_reference.asp

|||BTW - DocumentSourceType seems to be what you need, no? It allows you to draw the XML in from a variable or a string (which I suppose in theory you could bind to an expression =))
|||I have to say the use of indexes is a bit of a black art.

What if I want to get the value of multiple elements of a node.

i.e. <root><mynode value1="simon" value2="fred" />
<mynode value1="jamie" value2="smith" />
</root>

Can I iterate through mynode elements and store the value1 and value2 attributes.|||

SimonSa wrote:

I have to say the use of indexes is a bit of a black art.

What if I want to get the value of multiple elements of a node.

i.e. <root><mynode value1="simon" value2="fred" />
<mynode value1="jamie" value2="smith" />
</root>

Can I iterate through mynode elements and store the value1 and value2 attributes.


Simon,

I'm trying to do something almost identical to this but just can't get it working at the moment. I'll post up here if i get something useful working.

-Jamie|||I sent feedback about the help not being very helpful.

The help for the properties of the for each loop doesn't explain what each one is it just says 'set the value'. What else would I do with it. It needs to say what the value should be set to. Unlike other feedback. I didn't get a response on this one|||

SimonSa wrote:

I sent feedback about the help not being very helpful.

Me too. Doug Laudenshlager is good at taking feedback on board so expect something more useful in the future.

-Jamie|||

SimonSa wrote:

I have to say the use of indexes is a bit of a black art.

What if I want to get the value of multiple elements of a node.

i.e. <root><mynode value1="simon" value2="fred" />
<mynode value1="jamie" value2="smith" />
</root>

Can I iterate through mynode elements and store the value1 and value2 attributes.

Hi all,
OK, i'm progressing with this but have now hit EXACTLY the same problem as Simon. Here's my XML document:
<LastLoadDateList>
<Pair>
<StreamDetailID>3</StreamDetailID>
<LastLoadDate>2005-09-19 13:40:00</LastLoadDate>
</Pair>
<Pair>
<StreamDetailID>4</StreamDetailID>
<LastLoadDate>2005-09-19 13:42:15</LastLoadDate>
</Pair>
</LastLoadDateList>

I've managed to enumerate the 2 <Pair> nodes which results in the strings "32005-09-19 13:40:00" & "42005-09-19 13:42:15" getting enumerated. I've got EnumerationType=Nodetext.
Can you see what's happened here? Its concatenated the StreamDetailID & LastLoadDate nodes.

So how can I get those 2 values out into seperate variables? I guess its something to do with InnerXPathString but I can't see how to do it.

The lack of documentation around this is infuriating. To say the least!!!

Any help much appreciated!

-Jamie
|||<root>
<mynode value1="simon" value2="fred" />
<mynode value1="jamie" value2="smith" />
</root>

If your goal is to enumerate the attributes of the preceeding document, you could do so with an EnumerationType of NodeText and an OuterXPathString of /root/mynode/@.*|||<LastLoadDateList>
<Pair>
<StreamDetailID>3</StreamDetailID>
<LastLoadDate>2005-09-19 13:40:00</LastLoadDate>
</Pair>
<Pair>
<StreamDetailID>4</StreamDetailID>
<LastLoadDate>2005-09-19 13:42:15</LastLoadDate>
</Pair>
</LastLoadDateList>

If your goal is to enumerate the children of the Pair nodes in the preceeding document, you could do so with an EnumerationType of NodeText and an OuterXPathString of /LastLoadDateList/Pair/*|||Can the NodeList Enumerator be used to slice out a segment of an XML file and store it in a variable? Here's an example of what I would like to do. Given the following xml file:

<book>
<section>
<name>Chapter1</name>
<content>...</content>
</section>
<section>
<name>Chapter2</name>
<content>...</content>
</section>
</book>

I would like to use the NodeList Enumerator to loop twice over the XML and pull out the section into a variable, such that the variable would contain <section><name>Chapter1</name><content>...</content></section> in the first iteration and <section><name>Chapter2</name><content>...</content></section> in the second. Whatever I do, the enumerator either wants to map the different elements to different variables or store everything as text. Any help on this matter is appreciated.

Regards,
Lars R?nnb?ck|||If you set the index to -1 and the variable type to object and the outerXpath to \\section you should end up with the section in your object|||Should the enumerator type then be "Navigator" or "Node", and how would you transform the object variable back to string, so I could use it in an XSLT task?

Thanks for the tip about the -1 index, that seems to put everything into a single variable though.

Regards,
Lars|||Probably Node

and probably need to use a script component to convert the object to text.|||

Since others might be struggling with figuring out the InnerXPathString I thought I would post my experiences. I have the following recursive schema in the database for my typed XML datatype:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://garbleddomain/schemas/meta/jobb"
targetNamespace="http://garbleddomain/schemas/meta/jobb"
elementFormDefault="qualified">
<xs:element name="job">
<xs:annotation>
<xs:documentation>
<xhtml:p>
Defines a job.
</xhtml:p>
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element ref="job" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="script" type="xs:string" />
<xs:attribute name="type" default="Group">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Group" />
<xs:enumeration value="SP" />
<xs:enumeration value="SSIS" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

The schema is used to define jobs I want to run that can be grouped and hierarchical. Here's an example XML document:

<?xml version="1.0"?>
<job xmlns="http://garbleddomain/schemas/meta/jobb">
<job name="Loads">
<job name="Load customer data" script="sp_loadCust" type="SP" />
<job name="Load articles" script="sp_loadArticles" type="SP" />
</job>
<job name="Updates">
<job name="Update transactions" script="sp_updateTrans" type="SP" />
<job name="Update categories" script="UpdateCategories" type="SSIS" />
</job>
</job>

To retrieve the XML using an Execute SQL Task over OLE DB I set the ResultSet type to XML and used the following Direct Input query:

SELECT CAST(definition AS VARCHAR(max)) AS JobDefinition
FROM META_Job_TB
WHERE (JobID = ?)

In the Parameter Mapping section I map one String variable, User::JobID as Input with type VARCHAR and Parameter Name 0. In the Result Set section I map another variable User::JobDefinition with Result Name 0. This will pull the XML document above wrapped in <ROOT> tags.

Since I want to remove the <ROOT> tags and since I couldn't get SSIS to work with typed XML I have a cleanup step using an XML Task (XSLT) where I remove the tags and namespace. The XSLT is a Direct Input which looks as follows:

<?xml version="1.0" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:id="http://garbleddomain/schemas/meta/jobb"
exclude-result-prefixes="id">
<xsl:template match="/">
<xsl:apply-templates mode="copy-no-ns" select="/ROOT/id:job"/>
</xsl:template>
<xsl:template mode="copy-no-ns" match="*">
<xsl:element name="{name(.)}">
<xsl:copy-of select="@.*"/>
<xsl:apply-templates mode="copy-no-ns"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

I use the User::JobDefinition variable both as input source and output operation result destination. Now I am left with the job definition XML document without the namespace. In this case I want to iterate over the actual jobs and store the attributes in variables that can be accessible inside the loop, and do the following:

1. Create three String variables; User::JobName, User::JobScript, and User::JobType.
2. In the ForEach Loop I select the NodeList Enumerator.
3. I use the User::JobDefinition as document source.
4. Set EnumerationType to ElementCollection.
5. Set the OuterXPathString to //job[not(@.type = 'Group')]
6. Set the InnerElementType to NodeText.
7. Set the InnerXPathString to @.*
8. In Variable Mappings add the three String variables with Index 0, 1, and 2.

Voila, the variables will now be set to the values of the attributes for each job.

Hope this helps someone,
Regards,
Lars R?nnb?ck

Foreach NodeList Enumerator

Does anyone have any experience of using the NodeList enumerator in a Foreach loop? BOL is a bit light on this.

I want to enumerate over an XML Document that is passed into my package. The package is executed from a .net application.
Has anyone done anything like this?
Any demo material?
Should I pass the XML Document into an SSIS object variable or a String variable?
Can the NodeList enumerator enumerate an XML document that is stored in a String variable?
etc...
Thanks
JamieHey Jamie,
I've done this -- albeit for a rather simple example. I have an XML file that is just a persisted collection of structs with properties called "BusinessObjectName", so the data itself looks like this:
<DimensionInfos xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BusinessDimensionEntries>
<anyType xsi:type="BusinessDimensionInfo">
<BusinessObjectName>User</BusinessObjectName>
</anyType>
</BusinessDimensionEntries>
</DimensionInfos>

Essentially I want to iterate over all the nodes and pull out the "BusinessObjectName" from each. I created a foreach NodeList enumerator, document source is the file, enumeration type is NodeText, XPath source is DirectInput (meaning I specify it within the task) and the XPath string is "//BusinessObjectName". This query will recursively match all nodes of that type. Then I map index 0 to some variable and I will get the NodeText "User" (as specified) of the node(s) that match my XPath expression.
Not sure if you came across this article:
http://databasejournal.com/features/mssql/article.php/3528791
Also, a good XPath reference:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/html/_xpath_reference.asp

|||BTW - DocumentSourceType seems to be what you need, no? It allows you to draw the XML in from a variable or a string (which I suppose in theory you could bind to an expression =))
|||I have to say the use of indexes is a bit of a black art.

What if I want to get the value of multiple elements of a node.

i.e. <root><mynode value1="simon" value2="fred" />
<mynode value1="jamie" value2="smith" />
</root>

Can I iterate through mynode elements and store the value1 and value2 attributes.|||

SimonSa wrote:

I have to say the use of indexes is a bit of a black art.

What if I want to get the value of multiple elements of a node.

i.e. <root><mynode value1="simon" value2="fred" />
<mynode value1="jamie" value2="smith" />
</root>

Can I iterate through mynode elements and store the value1 and value2 attributes.


Simon,

I'm trying to do something almost identical to this but just can't get it working at the moment. I'll post up here if i get something useful working.

-Jamie|||I sent feedback about the help not being very helpful.

The help for the properties of the for each loop doesn't explain what each one is it just says 'set the value'. What else would I do with it. It needs to say what the value should be set to. Unlike other feedback. I didn't get a response on this one|||

SimonSa wrote:

I sent feedback about the help not being very helpful.

Me too. Doug Laudenshlager is good at taking feedback on board so expect something more useful in the future.

-Jamie|||

SimonSa wrote:

I have to say the use of indexes is a bit of a black art.

What if I want to get the value of multiple elements of a node.

i.e. <root><mynode value1="simon" value2="fred" />
<mynode value1="jamie" value2="smith" />
</root>

Can I iterate through mynode elements and store the value1 and value2 attributes.

Hi all,
OK, i'm progressing with this but have now hit EXACTLY the same problem as Simon. Here's my XML document:
<LastLoadDateList>
<Pair>
<StreamDetailID>3</StreamDetailID>
<LastLoadDate>2005-09-19 13:40:00</LastLoadDate>
</Pair>
<Pair>
<StreamDetailID>4</StreamDetailID>
<LastLoadDate>2005-09-19 13:42:15</LastLoadDate>
</Pair>
</LastLoadDateList>

I've managed to enumerate the 2 <Pair> nodes which results in the strings "32005-09-19 13:40:00" & "42005-09-19 13:42:15" getting enumerated. I've got EnumerationType=Nodetext.
Can you see what's happened here? Its concatenated the StreamDetailID & LastLoadDate nodes.

So how can I get those 2 values out into seperate variables? I guess its something to do with InnerXPathString but I can't see how to do it.

The lack of documentation around this is infuriating. To say the least!!!

Any help much appreciated!

-Jamie
|||<root>
<mynode value1="simon" value2="fred" />
<mynode value1="jamie" value2="smith" />
</root>

If your goal is to enumerate the attributes of the preceeding document, you could do so with an EnumerationType of NodeText and an OuterXPathString of /root/mynode/@.*|||<LastLoadDateList>
<Pair>
<StreamDetailID>3</StreamDetailID>
<LastLoadDate>2005-09-19 13:40:00</LastLoadDate>
</Pair>
<Pair>
<StreamDetailID>4</StreamDetailID>
<LastLoadDate>2005-09-19 13:42:15</LastLoadDate>
</Pair>
</LastLoadDateList>

If your goal is to enumerate the children of the Pair nodes in the preceeding document, you could do so with an EnumerationType of NodeText and an OuterXPathString of /LastLoadDateList/Pair/*|||Can the NodeList Enumerator be used to slice out a segment of an XML file and store it in a variable? Here's an example of what I would like to do. Given the following xml file:

<book>
<section>
<name>Chapter1</name>
<content>...</content>
</section>
<section>
<name>Chapter2</name>
<content>...</content>
</section>
</book>

I would like to use the NodeList Enumerator to loop twice over the XML and pull out the section into a variable, such that the variable would contain <section><name>Chapter1</name><content>...</content></section> in the first iteration and <section><name>Chapter2</name><content>...</content></section> in the second. Whatever I do, the enumerator either wants to map the different elements to different variables or store everything as text. Any help on this matter is appreciated.

Regards,
Lars R?nnb?ck|||If you set the index to -1 and the variable type to object and the outerXpath to \\section you should end up with the section in your object|||Should the enumerator type then be "Navigator" or "Node", and how would you transform the object variable back to string, so I could use it in an XSLT task?

Thanks for the tip about the -1 index, that seems to put everything into a single variable though.

Regards,
Lars|||Probably Node

and probably need to use a script component to convert the object to text.|||

Since others might be struggling with figuring out the InnerXPathString I thought I would post my experiences. I have the following recursive schema in the database for my typed XML datatype:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns="http://garbleddomain/schemas/meta/jobb"
targetNamespace="http://garbleddomain/schemas/meta/jobb"
elementFormDefault="qualified">
<xs:element name="job">
<xs:annotation>
<xs:documentation>
<xhtml:p>
Defines a job.
</xhtml:p>
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element ref="job" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="script" type="xs:string" />
<xs:attribute name="type" default="Group">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Group" />
<xs:enumeration value="SP" />
<xs:enumeration value="SSIS" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

The schema is used to define jobs I want to run that can be grouped and hierarchical. Here's an example XML document:

<?xml version="1.0"?>
<job xmlns="http://garbleddomain/schemas/meta/jobb">
<job name="Loads">
<job name="Load customer data" script="sp_loadCust" type="SP" />
<job name="Load articles" script="sp_loadArticles" type="SP" />
</job>
<job name="Updates">
<job name="Update transactions" script="sp_updateTrans" type="SP" />
<job name="Update categories" script="UpdateCategories" type="SSIS" />
</job>
</job>

To retrieve the XML using an Execute SQL Task over OLE DB I set the ResultSet type to XML and used the following Direct Input query:

SELECT CAST(definition AS VARCHAR(max)) AS JobDefinition
FROM META_Job_TB
WHERE (JobID = ?)

In the Parameter Mapping section I map one String variable, User::JobID as Input with type VARCHAR and Parameter Name 0. In the Result Set section I map another variable User::JobDefinition with Result Name 0. This will pull the XML document above wrapped in <ROOT> tags.

Since I want to remove the <ROOT> tags and since I couldn't get SSIS to work with typed XML I have a cleanup step using an XML Task (XSLT) where I remove the tags and namespace. The XSLT is a Direct Input which looks as follows:

<?xml version="1.0" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:id="http://garbleddomain/schemas/meta/jobb"
exclude-result-prefixes="id">
<xsl:template match="/">
<xsl:apply-templates mode="copy-no-ns" select="/ROOT/id:job"/>
</xsl:template>
<xsl:template mode="copy-no-ns" match="*">
<xsl:element name="{name(.)}">
<xsl:copy-of select="@.*"/>
<xsl:apply-templates mode="copy-no-ns"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

I use the User::JobDefinition variable both as input source and output operation result destination. Now I am left with the job definition XML document without the namespace. In this case I want to iterate over the actual jobs and store the attributes in variables that can be accessible inside the loop, and do the following:

1. Create three String variables; User::JobName, User::JobScript, and User::JobType.
2. In the ForEach Loop I select the NodeList Enumerator.
3. I use the User::JobDefinition as document source.
4. Set EnumerationType to ElementCollection.
5. Set the OuterXPathString to //job[not(@.type = 'Group')]
6. Set the InnerElementType to NodeText.
7. Set the InnerXPathString to @.*
8. In Variable Mappings add the three String variables with Index 0, 1, and 2.

Voila, the variables will now be set to the values of the attributes for each job.

Hope this helps someone,
Regards,
Lars R?nnb?ck

Tuesday, March 27, 2012

Foreach loop with XML Source failure

I can't import from XML files using a foreach loop. I load an XML file with a generated XSD. When I map the file to the table it has no errors. If I now go back and change to a different XML file, I get an error:

"Error 1 Validation error. Data Flow Task: DTS.Pipeline: input column "COLUMNNAME" (129) has lineage ID 2115 that was not previously used in the Data Flow task. Package.dtsx 0 0"

This is for testing purposes. When I run the foreach loop it does not work. Ironically, I do the exact same thing in another foreach loop with a completely different XML and it works fine.

Here is the broken XSD:

<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ComputerStatus">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="computer">
<xs:complexType>
<xs:attribute name="GUID" type="xs:string" use="optional" />
<xs:attribute name="WSUSServer" type="xs:string" use="optional" />
<xs:attribute name="WSUSGroup" type="xs:string" use="optional" />
<xs:attribute name="computerName" type="xs:string" use="optional" />
<xs:attribute name="OSBuild" type="xs:unsignedShort" use="optional" />
<xs:attribute name="OSSP" type="xs:unsignedByte" use="optional" />
<xs:attribute name="Model" type="xs:string" use="optional" />
<xs:attribute name="Make" type="xs:string" use="optional" />
<xs:attribute name="BIOS" type="xs:string" use="optional" />
<xs:attribute name="Processor" type="xs:string" use="optional" />
<xs:attribute name="LastReportedStatus" type="xs:string" use="optional" />
<xs:attribute name="LastSyncTime" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Help. Please. What have I done wrong. I imagine there is a flaw in my XML, but I can't pinpoint it.

Here is a sample of the XML file:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ComputerStatus>
<computerCount QTY="1" />
<computer GUID="edc2b6a5-5d86-467c-8c89-43fa18ae5921" WSUSServer="WSUS" WSUSGroup="THIS" computerName="COMPUTER" OSBuild="3790" OSSP="1" Model="COMPUTERTYPE" Make="HP" BIOS="1" Processor="x86" LastReportedStatus="10/25/2006 12:00:49 PM" LastSyncTime="10/25/2006 11:57:09 AM" />
</ComputerStatus>

That error says INPUT column, so I doubt its coming from the XML source adapter. An XML source adapter has output columns (and external metadata columns). Are you certain the error is with the source adapter and not some other pipeline component?

As an aside, that XSD and xml will work just fine in without regard the surrounding container. The XSD is not broken so far as use in the SSIS source adapter is concerned, although it does not contain the <computerCount> element.|||

Thank you for the feedback, but I think that I failed to mention that yes, the next thing that I send the XML Source to, whether it be a sort, derived column, an ole db destination, etc... is where the failure shows up.

Take for instance the case where I put the XML Source to an OLE DB Destination. I use a file and set the columns via regular mapping. Then I go back and set the XML Source to another file to be sure it continues to work and I get the error:

Error 1 Validation error. Data Flow Task: DTS.Pipeline: input column "WSUSServer" (5136) has lineage ID 4776 that was not previously used in the Data Flow task. Package.dtsx 0 0

Then I go back into the Ole DB Destination and have it map using Column Names. And everything is okay again. Then go back and switch to the next file and get this error:

Error 1 Validation error. Data Flow Task: DTS.Pipeline: input column "WSUSServer" (5136) has lineage ID 5265 that was not previously used in the Data Flow task. Package.dtsx 0 0

It's a vicious cycle.

An aside, to your aside, I was messing with the XSD and took out the ComputerCount during debug.

Thank you for your help.

sql

Monday, March 26, 2012

Foreach file

I loop through a list of files in a directory and one of the tasks in the container is to validate the xml file against dtd if this succeeds i process the file and the lforeachloop gets the next file. If validation fails i then delete that file,the problem i am having is that whe the xml task fails it stops the whole for each container even though the failparentonfailure is set to false.

How can i get the foreach container to continue to the next file after the xmltask fails (validation) and the file is succesfully deleted?

PS is their away of posting the DTSx screenshot as this might explain it better?

Try setting the xml task's ForceExecutionResults property to Success.|||

If the xml task(valid) is success i extract the nodes if it fails(invalid) i delete the file. If i force the success it will fail down the line when it tries to process an invalid xml file. i.e Get file --> if valid Process File/If invalid delete file --> Get next File.

Below the result of next task if a force success

[XML Task] Error: An error occurred with the following error message: "Data at the root level is invalid. Line 1, position 1.".

|||Set MaximumErrorCount (package properties) to some high number, perhaps 999 or something like that.

The default is 1, so even though you've told it not to fail the parent, the package still sees one error and then stops.|||

I dont want to tamper with the package error setting as some items exit on failure correctly. What i want is in my loop conatiner if the validate xml fails i delete the invalid file and get the next file. The scope of the failrwe is within the foreach loop and the only step i want it to continue looping through files is when i detect an invalid file and successfuly delete it.

I think it would be easier to understand what i am trying to do if i could post the screen shot of the control flow.

|||

MikeTomkies wrote:

I think it would be easier to understand what i am trying to do if i could post the screen shot of the control flow.

You can send me the screen shot via my posted e-mail on my profile. I can then host it and post it here.|||Did you get my screenshot, Anybody else able to help?

Monday, March 19, 2012

Force order of XML elements in FOR XML EXPLICIT

Hello,

I need to generate XML that matches an existing XSD. The XSD has the elements in a sequence requiring the XML elements to be in a specific order.

I want to generate XML like the following:

<employee>
<id>1</a>
<name>
<first>Nancy</first>
<last>Davolio</last>
</name>
<title>Sales Representative</title>
</employee>

When I perform my query using FOR XML EXPLICIT, how do I get the name element to be after the id element and before the title element?

Here is an example query (does not work, but illustrates what I would like):

select 1 as tag, null as parent,
EmployeeId as [employee!1!id!element],
null as [name!2!first!element],
null as [name!2!last!element],
Title as [employee!1!title!element]
from employees
where EmployeeId = 1

union all

select 2 as tag, 1 as parent,
EmployeeId as [employee!1!id!element],
FirstName as [name!2!first!element],
LastName as [name!2!last!element],
null as [employee!1!title!element]
from employees
where EmployeeId = 1

order by [employee!1!id!element], tag

for xml explicit

I know a possible solution is to create a tag #3 with [id!3] and parent = 1, but this requires an extra query from the employees table. If I have n elements after the name element, it would require n queries.

Any ideas?

Thanks!

Trev

I have the same problem. Is there a solution?

Travallion said "I know a possible solution is to create a tag #3 with [id!3] and parent = 1, but this requires an extra query from the employees table. If I have n elements after the name element, it would require n queries."

Could someone post an example of how to do it this way please?

Force order of XML elements in FOR XML EXPLICIT

Hello,

I need to generate XML that matches an existing XSD. The XSD has the elements in a sequence requiring the XML elements to be in a specific order.

I want to generate XML like the following:

<employee>
<id>1</a>
<name>
<first>Nancy</first>
<last>Davolio</last>
</name>
<title>Sales Representative</title>
</employee>

When I perform my query using FOR XML EXPLICIT, how do I get the name element to be after the id element and before the title element?

Here is an example query (does not work, but illustrates what I would like):

select 1 as tag, null as parent,
EmployeeId as [employee!1!id!element],
null as [name!2!first!element],
null as [name!2!last!element],
Title as [employee!1!title!element]
from employees
where EmployeeId = 1

union all

select 2 as tag, 1 as parent,
EmployeeId as [employee!1!id!element],
FirstName as [name!2!first!element],
LastName as [name!2!last!element],
null as [employee!1!title!element]
from employees
where EmployeeId = 1

order by [employee!1!id!element], tag

for xml explicit

I know a possible solution is to create a tag #3 with [id!3] and parent = 1, but this requires an extra query from the employees table. If I have n elements after the name element, it would require n queries.

Any ideas?

Thanks!

Trev

I have the same problem. Is there a solution?

Travallion said "I know a possible solution is to create a tag #3 with [id!3] and parent = 1, but this requires an extra query from the employees table. If I have n elements after the name element, it would require n queries."

Could someone post an example of how to do it this way please?

Monday, March 12, 2012

FOR XML? UPDATED ANSWER (WAS: Newbie question...)

Apologies on the last post. I did not see FOR XML and was thinking of other
SQL capabilities.
FOR XML creates a valid XML snippet, without root tags. This gives you a
couple of choices.
1. Create templates that supply root tags
2. Supply root tags in your program
For XML input into SQL Server, you WILL end up with a blow up, as mentioned
in the prior response.
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA
***************************
Think Outside the Box!
***************************
"VK" wrote:

> Hi,
> Will SQL XML (when we use FOR XML) perform check to make sure that XML
> document is in proper form or do we have to use a third party s/w like
> Altova to check for correctly created XML document?
> Many thanks for your time.
> *** Sent via Developersdex http://www.codecomments.com ***
> Don't just participate in USENET...get rewarded for it!
>
Let me clarify this a bit further.
FOR XML in most cases (except for invalid characters and when using the
xmltext directive in EXPLICIT mode) will generate well-formed fragments. You
can set a root property on your provider (ADO, ADO.net, or the HTTP ISAPI)
to have it wrapped.
When you use sp_xml_preparedocument to parse incoming XML data, you will get
an error message if the parsing fails. So it does not quite explode :-).
Best regards
Michael
"Cowboy (Gregory A. Beamer) - MVP" <NoSpamMgbworld@.comcast.netNoSpamM> wrote
in message news:B30C9949-8C15-46CE-826B-4961014B9B19@.microsoft.com...[vbcol=seagreen]
> Apologies on the last post. I did not see FOR XML and was thinking of
> other
> SQL capabilities.
> FOR XML creates a valid XML snippet, without root tags. This gives you a
> couple of choices.
> 1. Create templates that supply root tags
> 2. Supply root tags in your program
> For XML input into SQL Server, you WILL end up with a blow up, as
> mentioned
> in the prior response.
> --
> Gregory A. Beamer
> MVP; MCP: +I, SE, SD, DBA
> ***************************
> Think Outside the Box!
> ***************************
> "VK" wrote:

FOR XML? UPDATED ANSWER (WAS: Newbie question...)

Apologies on the last post. I did not see FOR XML and was thinking of other
SQL capabilities.
FOR XML creates a valid XML snippet, without root tags. This gives you a
couple of choices.
1. Create templates that supply root tags
2. Supply root tags in your program
For XML input into SQL Server, you WILL end up with a blow up, as mentioned
in the prior response.
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA
***************************
Think Outside the Box!
***************************
"VK" wrote:

> Hi,
> Will SQL XML (when we use FOR XML) perform check to make sure that XML
> document is in proper form or do we have to use a third party s/w like
> Altova to check for correctly created XML document?
> Many thanks for your time.
> *** Sent via Developersdex http://www.examnotes.net ***
> Don't just participate in USENET...get rewarded for it!
>Let me clarify this a bit further.
FOR XML in most cases (except for invalid characters and when using the
xmltext directive in EXPLICIT mode) will generate well-formed fragments. You
can set a root property on your provider (ADO, ADO.net, or the HTTP ISAPI)
to have it wrapped.
When you use sp_xml_preparedocument to parse incoming XML data, you will get
an error message if the parsing fails. So it does not quite explode :-).
Best regards
Michael
"Cowboy (Gregory A. Beamer) - MVP" <NoSpamMgbworld@.comcast.netNoSpamM> wrote
in message news:B30C9949-8C15-46CE-826B-4961014B9B19@.microsoft.com...
> Apologies on the last post. I did not see FOR XML and was thinking of
> other
> SQL capabilities.
> FOR XML creates a valid XML snippet, without root tags. This gives you a
> couple of choices.
> 1. Create templates that supply root tags
> 2. Supply root tags in your program
> For XML input into SQL Server, you WILL end up with a blow up, as
> mentioned
> in the prior response.
> --
> Gregory A. Beamer
> MVP; MCP: +I, SE, SD, DBA
> ***************************
> Think Outside the Box!
> ***************************
> "VK" wrote:
>

FOR XML: date returned without timezone

I'm querying a table with a datetime field using SELECT ... FOR XML. The
dates are returned in the following format:
<updated>2006-01-04T11:52:52.403</updated>
Is there any possiblity to add the timezone information to it? The result
should look as follows:
<updated>2006-01-04T11:52:52.403Z</updated>
The SQL statements looks like
SELECT date AS updated
FROM articles FOR XML PATH('entry')
Best regards
MartinI found a solution:
CONVERT(VARCHAR, date, 126) + 'Z' AS updated
126 is the style code for the ISO8601 date representation, i.e. XML
representation.
"Martin Szugat" wrote:

> I'm querying a table with a datetime field using SELECT ... FOR XML. The
> dates are returned in the following format:
> <updated>2006-01-04T11:52:52.403</updated>
> Is there any possiblity to add the timezone information to it? The result
> should look as follows:
> <updated>2006-01-04T11:52:52.403Z</updated>
> The SQL statements looks like
> SELECT date AS updated
> FROM articles FOR XML PATH('entry')
> Best regards
> Martin

FOR XML: date returned without timezone

I'm querying a table with a datetime field using SELECT ... FOR XML. The
dates are returned in the following format:
<updated>2006-01-04T11:52:52.403</updated>
Is there any possiblity to add the timezone information to it? The result
should look as follows:
<updated>2006-01-04T11:52:52.403Z</updated>
The SQL statements looks like
SELECT date AS updated
FROM articles FOR XML PATH('entry')
Best regards
Martin
I found a solution:
CONVERT(VARCHAR, date, 126) + 'Z' AS updated
126 is the style code for the ISO8601 date representation, i.e. XML
representation.
"Martin Szugat" wrote:

> I'm querying a table with a datetime field using SELECT ... FOR XML. The
> dates are returned in the following format:
> <updated>2006-01-04T11:52:52.403</updated>
> Is there any possiblity to add the timezone information to it? The result
> should look as follows:
> <updated>2006-01-04T11:52:52.403Z</updated>
> The SQL statements looks like
> SELECT date AS updated
> FROM articles FOR XML PATH('entry')
> Best regards
> Martin

For XML: create elements using cell values

Hi All,
If have a sql table with 2 columns and 2 rows with values
[["col1row1","col2row1"],["col1row2","col2row2"]].

Using t-SQL with "for xml"
How can i create a xml where the cell values (not column names) appear
as elements?
eg:
<col1row1>col2row1</col1row1>
<col1row2>col2row2</col1row2
Thanks,

slyi-- It can be done, but remember that you will have to
-- escape all the XML yourself

create table #test(
col1 varchar(8),
col2 varchar(8))

insert into #test(col1,col2)
values ('col1row1','col2row1')
insert into #test(col1,col2)
values ('col1row2','col2row2')

select 1 as Tag,
null as Parent,
'<'+col1+'>'+col2+'</'+col1+'>' as [TestNode!1!!xml]
from #test

order by Tag,[TestNode!1!!xml]
for xml explicit

drop table #test|||Thanks thats exactly what i needed to know|||On closer examination this wont work it gives

<TestNode><col1row1>col2row1</col1row1></TestNode>
<TestNode><col1row2>col2row2</col1row2></TestNode>
while i need something like
<TestNode>
<col1row1>col2row1</col1row1>
<col1row2>col2row2</col1row2>
</TestNode|||Unless someone else knows better, you're out of luck. Perhaps
you could look at redesigning the XML you are generating
and then apply an XSL transformation at the client.|||Thanks Mark. Could i create a temp table, with the cell values as
columns and build a sql xml query or loop from there?
Although im not too sure if that would work, very efficiently?|||(adrianca@.gmail.com) writes:
> Thanks Mark. Could i create a temp table, with the cell values as
> columns and build a sql xml query or loop from there?
> Although im not too sure if that would work, very efficiently?

I can't see that you can do this in SQL 2000 at all. Well, you can
build an nvarchar string that has the XML, and forego FOR XML
altogether, but if you exceed 4000 characters you lose anyway.

I think you need to build this document client-side.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||--something like below is what i was thinking but is it efficent?
--as the client side asp code works out very slow thats why i want to
do it on the sql server if possible

create table #test(
col1 varchar(8),
col2 varchar(8))

insert into #test(col1,col2)
values ('col1row1','col2row1')
insert into #test(col1,col2)
values ('col1row2','col2row2')

create table #xmltree( xmlblob text)
INSERT INTO #xmltree VALUES ('<table>')

Declare @.sqlq varchar(4000)
DECLARE @.textptr varbinary(16)
DECLARE @.bigtext varchar(8000)
DECLARE @.textlen int
DECLARE @.col1 varchar(32), @.col2 varchar(32)

SELECT @.textptr=TEXTPTR(xmlblob) FROM #xmltree

DECLARE tst_cursor CURSOR FOR select * from #test
OPEN tst_cursor
FETCH NEXT FROM tst_cursor into @.col1, @.col2
WHILE @.@.FETCH_STATUS = 0
BEGIN
SET @.bigtext='<'+ @.col1 + '>' +@.col2+'</'+ @.col1 + '>'
set @.textlen =(SELECT DATALENGTH(xmlblob) FROM #xmltree )
UPDATETEXT #xmltree.xmlblob @.textptr @.textlen 0 @.bigtext
FETCH NEXT FROM tst_cursor into @.col1, @.col2
END
CLOSE tst_cursor
DEALLOCATE tst_cursor
SET @.bigtext='</table>'
set @.textlen =(SELECT DATALENGTH(xmlblob) FROM #xmltree )
UPDATETEXT #xmltree.xmlblob @.textptr @.textlen 0 @.bigtext

select xmlblob from #xmltree

drop table #test
drop table #xmltree|||(adrianca@.gmail.com) writes:
> --something like below is what i was thinking but is it efficent?

More to the point: does it work?

> create table #xmltree( xmlblob text)
> INSERT INTO #xmltree VALUES ('<table>')

There is not really any way go get the xml from FOR XML into the table.
Well, you can get it to the client, and then INSERT back. Please don't
that. You're wasting bandwidth.

> --as the client side asp code works out very slow thats why i want to
> do it on the sql server if possible

For this sort of task, I would expect VBscript to be faster than T-SQL,
since we are only doing string manipulation.

You could write a program in C or C# for the task, but then you would have
to pass the XML string to the C program in some way. If you go by file,
you probably lose on the swings what you gain on the roundabout.

I should add the disclaimer that I have no knowledge about ASP
programming.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||asp 6 and asp.net both took about 10 sec to create the xml client side
from a sql table for a 50k table to xml

Using this method it now takes about 2 sec's by just displaying
resultset.

<%@. Page Language="C#" %
<%@. Import Namespace="System.Data.SqlClient" %
<script runat="server">
SqlConnection sqlConnection1;
SqlCommand sqlCommand1;

void Page_Load(Object Sender, EventArgs e) {

sqlConnection1 = new System.Data.SqlClient.SqlConnection();
sqlCommand1 = new System.Data.SqlClient.SqlCommand();
sqlConnection1.ConnectionString = "some connection details";
sqlConnection1.Open();
sqlCommand1.Connection = this.sqlConnection1;
sqlCommand1.CommandText = "sp_getaxml_dataisland";
Response.ContentType = "text/xml";
Response.Write(sqlCommand1.ExecuteScalar().ToStrin g());

}
</script
For me thats a performance gain worth taking.|||(adrianca@.gmail.com) writes:
> asp 6 and asp.net both took about 10 sec to create the xml client side
> from a sql table for a 50k table to xml

Just to check: how did you get the data to the client? You did get
all data into a dataset didn't you?

> sqlCommand1.CommandText = "sp_getaxml_dataisland";

sp_ is a prefix that is reserved for system stored procedure, and
SQL Server first looks in master for these. You should not use it
for your own code.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||>Just to check: how did you get the data to the client? You did get
>all data into a dataset didn't you?
Since the resultset is just one huge SQL Text datatype,
i just wrote it directly to the page, no need for the overhead of
creating a .net dataset object,
and then a javascript dataisland reads it directly.

eg: <xml id="my-dataisland" src="http://pics.10026.com/?src=getdataisland.aspx" /
>> sqlCommand1.CommandText = "sp_getaxml_dataisland";

>sp_ is a prefix that is reserved for system stored procedure, and
>SQL Server first looks in master for these. You should not use it
>for your own code.
Thanks for the tip i didnt know that.
Do you know if first checks the master table, will that slow down the
request correct / target sp?
I had thought you needed to put "master.dbo.sp_" to access a master sp?

Thanks for your help.|||(adrianca@.gmail.com) writes:
> Since the resultset is just one huge SQL Text datatype,
> i just wrote it directly to the page, no need for the overhead of
> creating a .net dataset object,
> and then a javascript dataisland reads it directly.

Javascript is maybe not the fastest. Can you save to a file, and run a
program in a non-interpreted langauge?

> Do you know if first checks the master table, will that slow down the
> request correct / target sp?
> I had thought you needed to put "master.dbo.sp_" to access a master sp?

In such case "sp_help" would not work. In fact when you say

somedatabase.dbo.sp_help tbl

what you get information about is somedatabase.dbo.tbl.

Exactly what happens is difficult describe, because it changes every
now and then. But if Microsoft would ship a system procedure called
sp_getaxml_dataisland, you would be in for a nasty surprise.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp

FOR XML works differently between Developer and Enterprise Edition in SQL 2005

If I run the same FOR XML query in a Development edition enviornment and a Enterprise Edition environment, the results are different. The query is exactly the same.

Here is the query:

DECLARE @.MessageBody XML
DECLARE @.AuditTable SYSNAME
DECLARE @.SendTrans BIT
DECLARE @.SendAudit BIT
DECLARE @.RecordCount INT
DECLARE @.OperationType CHAR(1)

SET @.RecordCount = @.@.ROWCOUNT
SET @.OperationType = 'U'
SET @.SendTrans = 1
SET @.SendAudit = 1
SET @.AuditTable = 'States'

SELECT @.MessageBody = (
SELECT * FROM
(
SELECT TOP 10
'INSERTED' AS ActionType, @.SendTrans AS SendTrans, @.SendAudit AS SendAudit,
COLUMNS_UPDATED() AS ColumnsUpdated, GETDATE() AS AuditDate,
@.AuditTable AS AuditTable, 'test' AS UserName, @.RecordCount AS RecordCount, *
FROM l_states
)AuditRecord
FOR XML AUTO, ROOT('AuditTable'), BINARY BASE64)

SELECT @.MessageBody

In my DEV env (Developer Edition), this result is produced:
<AuditTable>
<AuditRecord ActionType="INSERTED" SendTrans="1" SendAudit="1" AuditDate="2007-06-22T15:43:12.497" AuditTable="States" UserName="test" RecordCount="1" StateAbbreviation="AK" State="Alaska" />
<AuditRecord ActionType="INSERTED" SendTrans="1" SendAudit="1" AuditDate="2007-06-22T15:43:12.497" AuditTable="States" UserName="test" RecordCount="1" StateAbbreviation="AL" State="Alabama" />
</AuditTable>

In my Enterprise Edition evn, this is the result:
<AuditTable>
<AuditRecord ActionType="INSERTED" SendTrans="1" SendAudit="1" AuditDate="2007-06-22T15:44:48.230" AuditTable="States" UserName="test" RecordCount="1">
<l_states StateAbbreviation="AK" State="Alaska" />
<l_states StateAbbreviation="AL" State="Alabama" />
</AuditRecord>
</AuditTable>

Does anyone have any idea what might be wrong? Any help is greatly appreciated.
Tim

Tim,

What is the results of @.@.VERSION on both servers? (I suspect a difference in versions...)

For XML works different for different sql server 2005 editions

If I run the same FOR XML query in a Development edition enviornment and a Enterprise Edition environment, the results are different. The query is exactly the same.

Here is the query:

DECLARE @.MessageBody XML
DECLARE @.AuditTable SYSNAME
DECLARE @.SendTrans BIT
DECLARE @.SendAudit BIT
DECLARE @.RecordCount INT
DECLARE @.OperationType CHAR(1)

SET @.RecordCount = @.@.ROWCOUNT
SET @.OperationType = 'U'
SET @.SendTrans = 1
SET @.SendAudit = 1
SET @.AuditTable = 'States'

SELECT @.MessageBody = (
SELECT * FROM
(
SELECT TOP 10
'INSERTED' AS ActionType, @.SendTrans AS SendTrans, @.SendAudit AS SendAudit,
COLUMNS_UPDATED() AS ColumnsUpdated, GETDATE() AS AuditDate,
@.AuditTable AS AuditTable, 'test' AS UserName, @.RecordCount AS RecordCount, *
FROM l_states
)AuditRecord
FOR XML AUTO, ROOT('AuditTable'), BINARY BASE64)

SELECT @.MessageBody

In my DEV env (Developer Edition), this result is produced:
<AuditTable>
<AuditRecord ActionType="INSERTED" SendTrans="1" SendAudit="1" AuditDate="2007-06-22T15:43:12.497" AuditTable="States" UserName="test" RecordCount="1" StateAbbreviation="AK" State="Alaska" />
<AuditRecord ActionType="INSERTED" SendTrans="1" SendAudit="1" AuditDate="2007-06-22T15:43:12.497" AuditTable="States" UserName="test" RecordCount="1" StateAbbreviation="AL" State="Alabama" />
</AuditTable>

In my Enterprise Edition evn, this is the result:
<AuditTable>
<AuditRecord ActionType="INSERTED" SendTrans="1" SendAudit="1" AuditDate="2007-06-22T15:44:48.230" AuditTable="States" UserName="test" RecordCount="1">
<l_states StateAbbreviation="AK" State="Alaska" />
<l_states StateAbbreviation="AL" State="Alabama" />
</AuditRecord>
</AuditTable>

Does anyone have any idea what might be wrong? Any help is greatly appreciated.
TimYou might want to check the compat leve of two databases. The DEV behavior should level=90 (SQL 2005) behavior - using derived table name as row element name. The Ent is SQL 2000 behavior (level=80).

FOR XML vs. ADO

Hi,
Not sure if this is the best newsgroup to ask this so let me know if there
is a better one. I am in the process of investigating converting a componen
t
which uses ADO recordsets to return data from a DB, to making use of the FOR
XML statement. When using recordsets the default date format which is outpu
t
is DD/MM/YYYY hh:mm:ss. However, when using FOR XML the output format is
YYYY-MM-DDThh:mm:ss. This is a bit of pain to be honest since the formats
need to be the same to ensure backwards compatibility. What are the reasons
for the differences? What would be the best way to perform the formatting o
f
the FOR XML output, taking into account that performance is paramount and
that any SQL conversions would have to be propogated to all of the existing
SQL stored procs/views?
Thanks.> When using recordsets the default date format which is output
> is DD/MM/YYYY hh:mm:ss.
That is not correct. When the data leaves SQL Server, it has no format. It i
s the client application
that formats the data. Your assumption of the above format is probably becau
se you had a regional
setting on the machine where you ran the client app that formatted the data
in such way.
For XML, it is a different story, as XML is not binary data (which datetime
is). So a format had to
be chosen, and the most reasonable choice would be the international standar
d for datetime
formatting, ISO 8601, which I believe also is common in other XML implementa
tions. I do not
recommend changing the formatting in your XML document as that would divert
from accepted standards.
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"Lee" <Lee@.discussions.microsoft.com> wrote in message
news:139B3299-FF59-4F4D-9D6E-CD502F4DDD70@.microsoft.com...
> Hi,
> Not sure if this is the best newsgroup to ask this so let me know if there
> is a better one. I am in the process of investigating converting a compon
ent
> which uses ADO recordsets to return data from a DB, to making use of the F
OR
> XML statement. When using recordsets the default date format which is out
put
> is DD/MM/YYYY hh:mm:ss. However, when using FOR XML the output format is
> YYYY-MM-DDThh:mm:ss. This is a bit of pain to be honest since the formats
> need to be the same to ensure backwards compatibility. What are the reaso
ns
> for the differences? What would be the best way to perform the formatting
of
> the FOR XML output, taking into account that performance is paramount and
> that any SQL conversions would have to be propogated to all of the existin
g
> SQL stored procs/views?
> Thanks.|||Regardless of what format the data has when it leaves SQL Server ADO formats
the date into the DD/MM/YYYY hh:mm:ss format by default, on our machines. B
y
using FOR XML I can speed up the component by approx 10% but the format must
remain the same. If this means breaking an accepted standard then so be it,
if a different format was returned it would essentially mean that every
single object within the business logic tier would have to checked and
altered to ensure that the new format is supported.
So taking the above into account do you have any suggestions for the second
question - What would be the best way to perform the formatting of the FOR
XML output, taking into account that performance is paramount and that any
SQL conversions would have to be propogated to all of the existing SQL store
d
procs/views?
"Tibor Karaszi" wrote:

> That is not correct. When the data leaves SQL Server, it has no format. It
is the client application
> that formats the data. Your assumption of the above format is probably bec
ause you had a regional
> setting on the machine where you ran the client app that formatted the dat
a in such way.
> For XML, it is a different story, as XML is not binary data (which datetim
e is). So a format had to
> be chosen, and the most reasonable choice would be the international stand
ard for datetime
> formatting, ISO 8601, which I believe also is common in other XML implemen
tations. I do not
> recommend changing the formatting in your XML document as that would diver
t from accepted standards.
> --
> Tibor Karaszi, SQL Server MVP
> http://www.karaszi.com/sqlserver/default.asp
> http://www.solidqualitylearning.com/
> Blog: http://solidqualitylearning.com/blogs/tibor/
>
> "Lee" <Lee@.discussions.microsoft.com> wrote in message
> news:139B3299-FF59-4F4D-9D6E-CD502F4DDD70@.microsoft.com...
>|||Why would you think that datetime values need to be formatted at all - other
than for presentation purposes?
You could convert datetime values to character data and format it but that
would just break the domain. I.e. you'd have to convert it back in order to
use it programatically.
What exactly are you trying to achieve?
ML
http://milambda.blogspot.com/|||Lee (Lee@.discussions.microsoft.com) writes:
> Regardless of what format the data has when it leaves SQL Server ADO
> formats the date into the DD/MM/YYYY hh:mm:ss format by default, on our
> machines. By using FOR XML I can speed up the component by approx 10%
> but the format must remain the same. If this means breaking an accepted
> standard then so be it, if a different format was returned it would
> essentially mean that every single object within the business logic tier
> would have to checked and altered to ensure that the new format is
> supported.
> So taking the above into account do you have any suggestions for the
> second question - What would be the best way to perform the formatting
> of the FOR XML output, taking into account that performance is paramount
> and that any SQL conversions would have to be propogated to all of the
> existing SQL stored procs/views?
You can use the convert function in a query force a certain date format,
look up "CAST and CONVERT" in Books Online. But it is an extremely poor
idea to do, because that means you are shoving a date format down the
throat of your users. The likelihood that I will use your is likely to
be miniscule, but I want to see dates formatted as YYYY-MM-DD.
So for a good implementation, you should recevie the XML document as you
do now, and then convert the date client-side according to the regional
settings.
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx|||By no means is this an ideal scenario, I understand that. The framework I a
m
working with is a number of years old and I fear that the business objects
expect a certain date format which means that if this new date format was
used everything would go boom.
The only thing I was trying to acheive was a small performance increase
without having to change the code in too many components which means that I
would have to maintain exactly the same input and output. FOR XML provides
a
nice performance boost but the output is not exactly the same hence risking
the breaking of other components.
"ML" wrote:

> Why would you think that datetime values need to be formatted at all - oth
er
> than for presentation purposes?
> You could convert datetime values to character data and format it but that
> would just break the domain. I.e. you'd have to convert it back in order t
o
> use it programatically.
> What exactly are you trying to achieve?
>
> ML
> --
> http://milambda.blogspot.com/|||Maybe I didnt explain the situation correctly. This has nothing to do with
the presentation or what the user sees. This is to do with the format of
date that the business objects depend on to perform the required processing.
If these existing components suddenly get a new date format then it would
bring everything tumbline down hence why it is imperative that the output
from the data access component remains the same as to ensure full
compatibility.
I get the impression from the various replies that what I want is not
possible without making alterations to several other pieces of code.
"Erland Sommarskog" wrote:

> Lee (Lee@.discussions.microsoft.com) writes:
> You can use the convert function in a query force a certain date format,
> look up "CAST and CONVERT" in Books Online. But it is an extremely poor
> idea to do, because that means you are shoving a date format down the
> throat of your users. The likelihood that I will use your is likely to
> be miniscule, but I want to see dates formatted as YYYY-MM-DD.
> So for a good implementation, you should recevie the XML document as you
> do now, and then convert the date client-side according to the regional
> settings.
>
> --
> Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
> Books Online for SQL Server 2005 at
> http://www.microsoft.com/technet/pr...oads/books.mspx
> Books Online for SQL Server 2000 at
> http://www.microsoft.com/sql/prodin...ions/books.mspx
>|||> I get the impression from the various replies that what I want is not
> possible without making alterations to several other pieces of code.
To the best of my knowledge, there's no setting for this. The only option I
can think of would be to
indeed have CONVERT around the datetime column in every SELECT statement.
Tibor Karaszi, SQL Server MVP
http://www.karaszi.com/sqlserver/default.asp
http://www.solidqualitylearning.com/
Blog: http://solidqualitylearning.com/blogs/tibor/
"Lee" <Lee@.discussions.microsoft.com> wrote in message
news:6AD5B648-3CCF-4368-A4C8-741D28F253E8@.microsoft.com...
> Maybe I didnt explain the situation correctly. This has nothing to do wit
h
> the presentation or what the user sees. This is to do with the format of
> date that the business objects depend on to perform the required processin
g.
> If these existing components suddenly get a new date format then it would
> bring everything tumbline down hence why it is imperative that the output
> from the data access component remains the same as to ensure full
> compatibility.
> I get the impression from the various replies that what I want is not
> possible without making alterations to several other pieces of code.
> "Erland Sommarskog" wrote:
>|||Lee (Lee@.discussions.microsoft.com) writes:
> Maybe I didnt explain the situation correctly. This has nothing to do
> with the presentation or what the user sees. This is to do with the
> format of date that the business objects depend on to perform the
> required processing.
A horrible application design, in my opinion. If someone would change
the regional settings to US English, your business objects would choke -
or even worse: misinterpret the dates.

> If these existing components suddenly get a new date format then it would
> bring everything tumbline down hence why it is imperative that the output
> from the data access component remains the same as to ensure full
> compatibility.
> I get the impression from the various replies that what I want is not
> possible without making alterations to several other pieces of code.
Since you were to introduce XML into the pot, it appears that you are
into changing code anyway. You can get back dates in various formats
with XML, if you use the convert() function to format them as strings
in SQL Server.
But if you add XML, you will have to change the code client-side as
well, so I don't really see the problem with converting dates from
the XML documents to the regional settings.
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx

for xml to local variable

Is there a reason why the following does not work...
declare @.s varchar(1024)
set @.s = (select * from validTable for xml auto)
...assuming I know for a fact that the returned xml stream will fit inside my declared variable.
I suspect it's just the pre-compiler getting it's knickers in a knot over the * when this technically meets the requirements for setting a local variable.
... i think...
Does any one have any comments or ideas on how to achieve the same effect inside an SQL stored Proc.?
WR
Unfortunately, this can't be done in SQL Server 2000 - what actually gets
returned is a single column/single row resultset containing the XML stream.
The client-side components of SQLXML can extract that as a stream but
there's no way to do it in T-SQL.
In SQL Server 2005, you can use the xml data type to do what you're
suggesting.
Cheers,
Graeme
--
Graeme Malcolm
Principal Technologist
Content Master Ltd.
www.contentmaster.com
www.microsoft.com/mspress/books/6137.asp
"WildRide" <WildRide@.discussions.microsoft.com> wrote in message
news:06CEF1F3-F947-45B9-93BE-BE8FEF4E3DF6@.microsoft.com...
Is there a reason why the following does not work...
declare @.s varchar(1024)
set @.s = (select * from validTable for xml auto)
...assuming I know for a fact that the returned xml stream will fit inside
my declared variable.
I suspect it's just the pre-compiler getting it's knickers in a knot over
the * when this technically meets the requirements for setting a local
variable.
... i think...
Does any one have any comments or ideas on how to achieve the same effect
inside an SQL stored Proc.?
WR
|||sorry but i have testing this code with sqlserver 2000
and it doesent work
Cdlt
Query:
declare @.s varchar(1024)
set @.s = (select * from USERPROFILE for xml auto)
Result:
Server: Msg 170, Level 15, State 1, Line 2
Line 2: Incorrect syntax near 'xml'.

>--Original Message--
>Unfortunately, this can't be done in SQL Server 2000 -
what actually gets
>returned is a single column/single row resultset
containing the XML stream.
>The client-side components of SQLXML can extract that as
a stream but
>there's no way to do it in T-SQL.
>In SQL Server 2005, you can use the xml data type to do
what you're
>suggesting.
>Cheers,
>Graeme
>--
>--
>Graeme Malcolm
>Principal Technologist
>Content Master Ltd.
>www.contentmaster.com
>www.microsoft.com/mspress/books/6137.asp
>
>"WildRide" <WildRide@.discussions.microsoft.com> wrote in
message
>news:06CEF1F3-F947-45B9-93BE-BE8FEF4E3DF6@.microsoft.com...
>Is there a reason why the following does not work...
>declare @.s varchar(1024)
>set @.s = (select * from validTable for xml auto)
>...assuming I know for a fact that the returned xml
stream will fit inside
>my declared variable.
>I suspect it's just the pre-compiler getting it's
knickers in a knot over
>the * when this technically meets the requirements for
setting a local
>variable.
>... i think...
>Does any one have any comments or ideas on how to achieve
the same effect
>inside an SQL stored Proc.?
>WR
>
>.
>
|||"Boss Hog" <anonymous@.discussions.microsoft.com> wrote in message
news:74c001c4764f$9c4d6bb0$a301280a@.phx.gbl...
> sorry but i have testing this code with sqlserver 2000
> and it doesent work
It won't work because it isn't supported.
Bryant

FOR XML streamed?

We are trying to write an XSLT report generator that is pipelined throughout all stages. The first step in the process is to get XML out of our database. We are using 2005 April CTP. The white paper by Michael Rys in the MSDN library seems to indicate that the FOR XML streaming behavior of SQL 2000 is still present in 2005. However, it seems to hint that if you use the TYPE directive to return your XML in an actual native XML field, then the XML is no longer streamed. The entire document may first be created and then sent back all at once as a scaler XML field.

Here are the 2 FOR XML clauses we are expirimenting with:

"For XML Path('PurchaseOrder'), Type, Root('PurchaseOrderReport')" - sends back an XML field instance.

"For XML Path('PurchaseOrder'), Root('PurchaseOrderReport')" - sends back an nvarchar(max) instance.

Can anyone answer if using the TYPE directive eliminates the streaming behavior and therefore defeats our attempt to pipeline?

Thanks!

The TYPE directive will create an XML datatype instance and thus will "Blob" on the server before sending the result back to give you the guarantee of a well-formed XML datatype instance.

So: yes, it eliminates the streaming. You can still pipeline after that on the client side though for the rest of your pipeline.

Best regards
Michael|||Thanks for the reply Michael!

Aside from the guarentee of well formed XML, are there other advantages/disadvantages to using the TYPE directive that we should concider when trying to decide between the typed or non-typed route?|||The TYPE directive constructs an XML data type instance, so you can use it for

(a) nested FOR XML
(b) assignment to XML columns, variables and parameters
(c) querying the XML data type result using XQuery

at the server. If your intent is to get the XML to the client in a streamable manner, and (a)-(c) don't apply, then you are better off without the TYPE directive. This also saves you the cost of data conversion to XML data type.

Hope this helps.

Thank you,

Shankar
Program Manager, Microsoft SQL Server

FOR XML return as a Scalar

When returning a result as XML using FOR XML SQL Server 2005 is returning
serveral rows when the result is greater than 2036 in length. Each row is
breaking on this length. I would like FOR XML to return all the xml in a
singe row single column so that I can use a select scalar for the results.
Currently I have to use a data reader and a string builder. I'm hoping that
there is a way to control the size if the output for FOR XML so that I can d
o
a scalar read of any result.
Thanks,
TylerHi Tyler,
Please post your statement for us to take a look at.
Thanks,
Tony
Tony Rogerson
SQL Server MVP
http://sqlserverfaq.com - free video tutorials
"Tyler Carver" <Tyler Carver@.discussions.microsoft.com> wrote in message
news:DE8A3709-2E31-49F6-B30C-C93B4B1195E0@.microsoft.com...
> When returning a result as XML using FOR XML SQL Server 2005 is returning
> serveral rows when the result is greater than 2036 in length. Each row is
> breaking on this length. I would like FOR XML to return all the xml in a
> singe row single column so that I can use a select scalar for the results.
> Currently I have to use a data reader and a string builder. I'm hoping
> that
> there is a way to control the size if the output for FOR XML so that I can
> do
> a scalar read of any result.
> Thanks,
> Tyler|||In SQL 2005 you can use the TYPE directive to get a scalar XML value like:
SELECT * FROM tbl FOR XML AUTO, TYPE
In SQL 2000, you cannot do this directly in Query Analyzer. FOR XML returns
an XML stream which can be retreived as single string only if you use an API
which supports a stream interface. Since Query Analyer uses ODBC, the values
will be munged to 2032 characters per row.
One alternative is to use XML EXPLICIT with the edge table ( need to know
the resultset upfront ). Another is to extract the data externally ( to an
app or flat file ) and stitch them back together to form single XML
document.
Anith|||"Tony Rogerson" wrote:
> Please post your statement for us to take a look at.
Here is a SQL statement that returns a large XML result:
SELECT *
FROM Categories
FOR XML PATH('Category'), ROOT('ArrayOfCategory'), TYPE
This returns serveral rows from the database that need to be concatenated.
I want to change the statement so that only one row one column is returned.
Tyler|||For test...
select name as [text()]
from sys.objects
for xml path( '' ), root( 'sysobjects' ), type
So yours would be...
SELECT *
FROM Categories
FOR XML PATH(''), ROOT('ArrayOfCategory'), TYPE
Tony.
--
Tony Rogerson
SQL Server MVP
http://sqlserverfaq.com - free video tutorials
"Tyler Carver" <TylerCarver@.discussions.microsoft.com> wrote in message
news:E46BBA07-4B47-4C49-B5B6-BC4D69F66E65@.microsoft.com...
> "Tony Rogerson" wrote:
> Here is a SQL statement that returns a large XML result:
> SELECT *
> FROM Categories
> FOR XML PATH('Category'), ROOT('ArrayOfCategory'), TYPE
> This returns serveral rows from the database that need to be concatenated.
> I want to change the statement so that only one row one column is
> returned.
> Tyler|||Are you using SSMS? Can you post the results of:
DECLARE @.xml AS XML
SET @.xml = ( SELECT *
FROM Categories
FOR XML PATH('Category'), ROOT('ArrayOfCategory'), TYPE )
SELECT DATALENGTH( @.xml )
Are you getting an error?
Anith|||Sorry, you'll need a delimiter as well...
select name + ',' as [text()]
from sys.objects
for xml path( '' ), root( 'sysobjects' ), type
Tony Rogerson
SQL Server MVP
http://sqlserverfaq.com - free video tutorials
"Tony Rogerson" <tonyrogerson@.sqlserverfaq.com> wrote in message
news:u3ACF6b%23FHA.2040@.TK2MSFTNGP14.phx.gbl...
> For test...
> select name as [text()]
> from sys.objects
> for xml path( '' ), root( 'sysobjects' ), type
> So yours would be...
> SELECT *
> FROM Categories
> FOR XML PATH(''), ROOT('ArrayOfCategory'), TYPE
> Tony.
> --
> Tony Rogerson
> SQL Server MVP
> http://sqlserverfaq.com - free video tutorials
>
> "Tyler Carver" <TylerCarver@.discussions.microsoft.com> wrote in message
> news:E46BBA07-4B47-4C49-B5B6-BC4D69F66E65@.microsoft.com...
>|||"Anith Sen" wrote:
> In SQL 2005 you can use the TYPE directive to get a scalar XML value like:
Thanks Anith, this is exactly what I was looking for. We had several sprocs
without the Type directive and the example I had happened to have it and was
therefore unknown to us, working.
Thanks, again.
Tyler

for xml raw problem

Hi
I'm running a simple query with for xml raw on a table
one of columns in select clause here is of type text and stores xml
file itself.
The problem i'm facing is when I get this text back from this column I
get back unformatted xml
e.g
instead of getting <GPF> I get <GPF> etc
How do I get this column as formatted xml text ?
Thanks for help
Vishy>
> I'm running a simple query with for xml raw on a table
> one of columns in select clause here is of type text and stores xml
> file itself.
> The problem i'm facing is when I get this text back from this column I
> get back unformatted xml
> e.g
> instead of getting <GPF> I get <GPF> etc
> How do I get this column as formatted xml text ?
>
Hello
signs '<' and '>' are very important in XML because they show begin and end
of xml element, so when an element or attribute value has such signs it must
be changed into < and >. But when you open XML which contains such
substitution - using DOM or OPENXML in SQL you will get values with signs
'<', '>'. So I think that it sould not be a problem - siply try to process
XML which was generated and you will see that it has valid values of
elements/attributes.
I hope it helps,
Alwik|||Thanks Alwik for reply
I tried to create object on XmlDocument using LoadXml() method
it loads up the xml successfully but if I want to run any Xpath; it
fails
as <GPF> is not treated as <GPF> so I can't find GPF element
is there any work around?
Vishy|||Are you using SQL Server 2000 or 2005?
In the case of SQL Server 2000, you will have to use the explicit mode and
its !xml directive, if you want to have string data be inlined into the XML
structure.
In the case of SQL Server 2005, you can stick with the FOR XML RAW query,
but you need to cast the string data to XML in the select clause.
Best regards
Michael
"Vishy" <vishal.halbe@.gmail.com> wrote in message
news:1128445808.595093.141180@.g49g2000cwa.googlegroups.com...
> Thanks Alwik for reply
> I tried to create object on XmlDocument using LoadXml() method
> it loads up the xml successfully but if I want to run any Xpath; it
> fails
> as <GPF> is not treated as <GPF> so I can't find GPF element
> is there any work around?
> Vishy
>|||Thanks Michael for reply
I'm using SQL 2000
Vishy

for xml raw problem

Hi
I'm running a simple query with for xml raw on a table
one of columns in select clause here is of type text and stores xml
file itself.
The problem i'm facing is when I get this text back from this column I
get back unformatted xml
e.g
instead of getting <GPF> I get <GPF> etc
How do I get this column as formatted xml text ?
Thanks for help
Vishy
>
> I'm running a simple query with for xml raw on a table
> one of columns in select clause here is of type text and stores xml
> file itself.
> The problem i'm facing is when I get this text back from this column I
> get back unformatted xml
> e.g
> instead of getting <GPF> I get <GPF> etc
> How do I get this column as formatted xml text ?
>
Hello
signs '<' and '>' are very important in XML because they show begin and end
of xml element, so when an element or attribute value has such signs it must
be changed into < and >. But when you open XML which contains such
substitution - using DOM or OPENXML in SQL you will get values with signs
'<', '>'. So I think that it sould not be a problem - siply try to process
XML which was generated and you will see that it has valid values of
elements/attributes.
I hope it helps,
Alwik
|||Thanks Alwik for reply
I tried to create object on XmlDocument using LoadXml() method
it loads up the xml successfully but if I want to run any Xpath; it
fails
as <GPF> is not treated as <GPF> so I can't find GPF element
is there any work around?
Vishy
|||Are you using SQL Server 2000 or 2005?
In the case of SQL Server 2000, you will have to use the explicit mode and
its !xml directive, if you want to have string data be inlined into the XML
structure.
In the case of SQL Server 2005, you can stick with the FOR XML RAW query,
but you need to cast the string data to XML in the select clause.
Best regards
Michael
"Vishy" <vishal.halbe@.gmail.com> wrote in message
news:1128445808.595093.141180@.g49g2000cwa.googlegr oups.com...
> Thanks Alwik for reply
> I tried to create object on XmlDocument using LoadXml() method
> it loads up the xml successfully but if I want to run any Xpath; it
> fails
> as <GPF> is not treated as <GPF> so I can't find GPF element
> is there any work around?
> Vishy
>
|||Thanks Michael for reply
I'm using SQL 2000
Vishy

FOR XML RAW & Null Characters Bug

Just curious if anyone else has seen this issue:
We had a situation where the XML being retrieved from an XML Explicit query
was malformed. After looking at the resulting XML from the query being ran
with different sets of paramaters we were able to identify that the building
of the XML was stopping on the same value. Looking further we noticed this
field had a null character (ASCII code of 0).
Here's a simple example showing the issue:
declare @.var varchar(100)
set @.var='Josh' + CHAR(0)
select @.var AS Col
for XML RAW
this results in <row Col="Josh
I couldn't find if this was a documented bug or expected behavior? Does
anyone know of any articles that describe how the null character is handled
in SQL?
Thanks
JoshOn Mon, 30 Jan 2006 13:05:31 -0800, joshb wrote:

>Just curious if anyone else has seen this issue:
>We had a situation where the XML being retrieved from an XML Explicit query
>was malformed. After looking at the resulting XML from the query being ran
>with different sets of paramaters we were able to identify that the buildin
g
>of the XML was stopping on the same value. Looking further we noticed this
>field had a null character (ASCII code of 0).
>Here's a simple example showing the issue:
>declare @.var varchar(100)
>set @.var='Josh' + CHAR(0)
>select @.var AS Col
>for XML RAW
>this results in <row Col="Josh
>I couldn't find if this was a documented bug or expected behavior? Does
>anyone know of any articles that describe how the null character is handled
>in SQL?
Hi Josh,
The problem is that ASCII 0 is used as a string delimiter in many
languages. So the low-level code that sends the results to the screen
sees the ASCII 0 and thinks it's the end of the string.
Try running your code from another client (e.g. osql).
Hugo Kornelis, SQL Server MVP|||Hi, Josh
The problem is fixed in SQL Server 2005, where your example returns
this (in Management Studio or in Query Analyzer):
<row Col="Josh�"/>
However, Management Studio warns that the character with the code 0x0
is illegal in XML documents.
Razvan