FOR XML PATH('')),1,1,'')这是啥意思

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FOR XML PATH('')),1,1,'')这是啥意思相关的知识,希望对你有一定的参考价值。

在SQLServer中,FORXMLPATH语句用于根据查询的数量生成XML数据。PATH()括号中的参数是控制节点的名称。

for语句使问题C语言提供的答案更加强大,并使用了更加广泛和专门化的循环语句,其一般形式为:for表达式1.2.3。

SQL(结构化查询语言)是一种数据库查询和编程语言,用于访问数据、查询、更新和管理关系数据库系统。SQL是一种高级的非过程性编程语言,允许用户使用高级数据结构。

它不要求用户指定数据的存储方法,也不要求用户知道数据的具体存储方法,因此具有完全不同底层结构的不同数据库系统可以使用相同的SQL语言作为数据输入和管理的接口。

扩展资料:

SQL语言由四个部分组成:

数据定义语言(DDL),如创建、删除、修改等。

数据操作语言(DML),如插入、更新、删除语句。

数据查询语言,如SELECT语句。

数据控制语言,如授予、撤销、提交、回滚等。

SQL语言包括两大类编程语言:数据定义语言(DDL)和数据操作语言(DML)。

以下是其中的两个:

编辑本节DDL

DDL语句通常包括每个对象的CREATE、ALTER和DROP命令。例如,像CREATETABLE、ALTERTABLE和DROPTABLE这样的语句可以用来创建新表、修改它们的属性(比如添加或删除行)删除表等等。

CREATETABLE语句

使用DDL在MyDB数据库中创建一个名为Customer_Data的示例表,我们将在本章后面的示例中使用这个表,如前所述,CREATETABLE语句可用于创建表,示例表定义为四行。

参考技术A 这个语句不完整。应该是这样:
stuff(select ',' + fieldname from tablename for xml path('')),1,1,'')
这一整句的作用是将多行fieldname字段的内容串联起来,用逗号分隔。
例如表
fieldname
-----------
AAA
BBB
CCC
串联之后就是字符串: AAA,BBB,CCC
for xml path是SQL Server 2005以后版本支持的一种生成XML的方式。具体如何使用,请参考联机丛书。
stuff函数的作用是去掉字符串最前面的逗号分隔符。
参考技术B SQL Server中利用 FOR XML PATH 语句能够把查询的数据生成XML数据,
其中PATH() 括号内的参数是控制节点名称

sql SELECT XML,FOR XML,FOR XML RAW,AUTO,FOR XML PATH,FOR XML EXPLICIT.sql

/*
You can use the FOR XML clause to take relational results and return them as XML code. There are different modes:

RAW - an XML representation of a rowset. It doesn't make any attempt to interpret the elements in the document and identify what they represent. Returns an element for each row in the rowset. Results can be element or attribute-centric. You can specify an optional root element and row element name. If you don't specify a row element name, it'll be called <row>.

AUTO - creates nested child-elements for joined tables, attempting to find a structure to the data. You don't have to specifically name the elements - they are named to match the table they're pulled from (or the alias you specify). Results can be element or attribute-centric, and you can specify a root element.

PATH - uses XML Path Language (XPath) to specify the XML format you want to return. Allows you to create nested data and what should be exposed as an element or an attribute. Easier to use than EXPLICIT mode.

EXPLICIT - based on a tabular representation of XML documents, and enables complete control over the XML structure. This allows you to mix and match it being attribute-centric AND element-centric. You can create multiple levels in the hierarchy by creating multiple SELECT satements and UNIONing them together (one SELECT statement per level in the hierarchy). Read up on this if you ever want to use this. Uses a very specific naming convention such as [Invoice!1!FName!Element].

*/

-- for all of the examples below, here is the original query and the relational data that it would normally return
SELECT c.CustomerID AS CustID, c.LastName AS PersonName,
soh.SalesOrderID, soh.OrderDate, soh.TotalDue
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
ORDER BY c.CustomerID

/* TOP 5 of regular relational resultset returned:

CustID	PersonName	SalesOrderID	OrderDate	TotalDue
11000	Yang	43793	2011-06-21 00:00:00.000	3756.989
11000	Yang	51522	2013-06-20 00:00:00.000	2587.8769
11000	Yang	57418	2013-10-03 00:00:00.000	2770.2682
11001	Huang	51493	2013-06-18 00:00:00.000	2674.0227
11001	Huang	43767	2011-06-17 00:00:00.000	3729.364

*/

--------------
-- RAW MODE --
--------------

-- RAW - an XML representation of a rowset. It doesn't make any attempt to interpret the elements in the document and identify what they represent. Returns an element for each row in the rowset. Results can be element or attribute-centric. You can specify an optional root element and row element name. If you don't specify a row element name, it'll be called <row>.
SELECT c.CustomerID AS CustID, c.LastName AS PersonName,
soh.SalesOrderID, soh.OrderDate, soh.TotalDue
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
ORDER BY c.CustomerID
FOR XML RAW;

/* Result of FOR XML RAW, which returns a single row resultset that contains XML code for the entire resultset - it creates a <row> element for each row, and places all of the data in as attributes

<row CustID="11000" PersonName="Yang" SalesOrderID="43793" OrderDate="2011-06-21T00:00:00" TotalDue="3756.9890" />
<row CustID="11000" PersonName="Yang" SalesOrderID="51522" OrderDate="2013-06-20T00:00:00" TotalDue="2587.8769" />
<row CustID="11000" PersonName="Yang" SalesOrderID="57418" OrderDate="2013-10-03T00:00:00" TotalDue="2770.2682" />
<row CustID="11001" PersonName="Huang" SalesOrderID="51493" OrderDate="2013-06-18T00:00:00" TotalDue="2674.0227" />
<row CustID="11001" PersonName="Huang" SalesOrderID="43767" OrderDate="2011-06-17T00:00:00" TotalDue="3729.3640" />
<row CustID="11001" PersonName="Huang" SalesOrderID="72773" OrderDate="2014-05-12T00:00:00" TotalDue="650.8008" />

*/

-- you can also rename the <row> element by placing it in parenthesis after the word RAW, and you can include a ROOT clause to add a root element.
SELECT c.CustomerID AS CustID, c.LastName AS PersonName,
soh.SalesOrderID, soh.OrderDate, soh.TotalDue
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
ORDER BY c.CustomerID
-- renames the <row> element as <order>, and wraps everything within a root element called <orders>
FOR XML RAW('Order'), ROOT('Orders');

/*
<Orders>
  <Order CustID="11000" PersonName="Yang" SalesOrderID="43793" OrderDate="2011-06-21T00:00:00" TotalDue="3756.9890" />
  <Order CustID="11000" PersonName="Yang" SalesOrderID="51522" OrderDate="2013-06-20T00:00:00" TotalDue="2587.8769" />
  <Order CustID="11000" PersonName="Yang" SalesOrderID="57418" OrderDate="2013-10-03T00:00:00" TotalDue="2770.2682" />
  <Order CustID="11001" PersonName="Huang" SalesOrderID="51493" OrderDate="2013-06-18T00:00:00" TotalDue="2674.0227" />
  <Order CustID="11001" PersonName="Huang" SalesOrderID="43767" OrderDate="2011-06-17T00:00:00" TotalDue="3729.3640" />
  ...
*/

-- you can also make the results element-centric by adding the ELEMENTS keyword, which will return all row values as elements instead of attributes
SELECT c.CustomerID AS CustID, c.LastName AS PersonName,
soh.SalesOrderID, soh.OrderDate, soh.TotalDue
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
ORDER BY c.CustomerID
-- renames <row> element as <order>, creates a root element <orders>, and specifies results to be returned as elements instead of attributes
FOR XML RAW('Order'), ROOT('Orders'), ELEMENTS;

/* Results of RAW using ELEMENT-centric results rather than attribute-centric results
<Orders>
  <Order>
    <CustID>11000</CustID>
    <PersonName>Yang</PersonName>
    <SalesOrderID>43793</SalesOrderID>
    <OrderDate>2011-06-21T00:00:00</OrderDate>
    <TotalDue>3756.9890</TotalDue>
  </Order>
  <Order>
    <CustID>11000</CustID>
    <PersonName>Yang</PersonName>
    <SalesOrderID>51522</SalesOrderID>
    <OrderDate>2013-06-20T00:00:00</OrderDate>
    <TotalDue>2587.8769</TotalDue>
  </Order>
  <Order>
    <CustID>11000</CustID>
    <PersonName>Yang</PersonName>
    <SalesOrderID>57418</SalesOrderID>
    <OrderDate>2013-10-03T00:00:00</OrderDate>
    <TotalDue>2770.2682</TotalDue>
  </Order>
  ...
*/

---------------
-- AUTO MODE --
---------------

-- AUTO - creates nested child-elements for joined tables, attempting to find a structure to the data. You don't have to specifically name the elements - they are named to match the table they're pulled from (or the alias you specify). Results can be element or attribute-centric, and you can specify a root element.
SELECT c.CustomerID AS CustID, c.LastName AS PersonName,
soh.SalesOrderID, soh.OrderDate, soh.TotalDue
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
ORDER BY c.CustomerID
-- FOR XML AUTO, note that you don't have to name the rows, it'll pull the rows based on the table name (or in this case the alias name).
FOR XML AUTO, ROOT('Orders');

/* Results for AUTO mode. Note the elements are named after the table aliases, and it's automatically created the rows from the SalesOrderHeader table as child elements to the rows from the Customer table.
<Orders>
  <c CustID="11000" PersonName="Yang">
    <soh SalesOrderID="43793" OrderDate="2011-06-21T00:00:00" TotalDue="3756.9890" />
    <soh SalesOrderID="51522" OrderDate="2013-06-20T00:00:00" TotalDue="2587.8769" />
    <soh SalesOrderID="57418" OrderDate="2013-10-03T00:00:00" TotalDue="2770.2682" />
  </c>
  <c CustID="11001" PersonName="Huang">
    <soh SalesOrderID="51493" OrderDate="2013-06-18T00:00:00" TotalDue="2674.0227" />
    <soh SalesOrderID="43767" OrderDate="2011-06-17T00:00:00" TotalDue="3729.3640" />
    <soh SalesOrderID="72773" OrderDate="2014-05-12T00:00:00" TotalDue="650.8008" />
  </c>
  <c CustID="11002" PersonName="Torres">
    <soh SalesOrderID="43736" OrderDate="2011-06-09T00:00:00" TotalDue="3756.9890" />
    <soh SalesOrderID="51238" OrderDate="2013-06-02T00:00:00" TotalDue="2535.9640" />
    <soh SalesOrderID="53237" OrderDate="2013-07-26T00:00:00" TotalDue="2673.0613" />
  </c>
  ...

*/

-- you can also make it element-centric using ELEMENTS
SELECT c.CustomerID AS CustID, c.LastName AS PersonName,
soh.SalesOrderID, soh.OrderDate, soh.TotalDue
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
ORDER BY c.CustomerID
-- FOR XML AUTO, note that you don't have to name the rows, it'll pull the rows based on the table name (or in this case the alias name).
FOR XML AUTO, ROOT('Orders'), ELEMENTS;

/* Results for AUTO mode. Note each table has its own element, and the columns are then returned as child elements.
<Orders>
  <c>
    <CustID>11000</CustID>
    <PersonName>Yang</PersonName>
    <soh>
      <SalesOrderID>43793</SalesOrderID>
      <OrderDate>2011-06-21T00:00:00</OrderDate>
      <TotalDue>3756.9890</TotalDue>
    </soh>
    <soh>
      <SalesOrderID>51522</SalesOrderID>
      <OrderDate>2013-06-20T00:00:00</OrderDate>
      <TotalDue>2587.8769</TotalDue>
    </soh>
    <soh>
      <SalesOrderID>57418</SalesOrderID>
      <OrderDate>2013-10-03T00:00:00</OrderDate>
      <TotalDue>2770.2682</TotalDue>
    </soh>
  </c>
  ...

*/

---------------
-- PATH MODE --
---------------

-- PATH - uses XML Path Language (XPath) to specify the XML format you want to return. Allows you to create nested data and what should be exposed as an element or an attribute. Easier to use than EXPLICIT mode.

-- example of using XPATH. Everything with an @ symbol will be returned as an attribute, and everything without an @ will be returned as an element. Apparently all of the attributes in a sibling grouping must be listed first, then the elements.
SELECT c.CustomerID AS '@CustID', 
soh.SalesOrderID AS '@SalesID', 
c.LastName AS 'PersonName',
soh.OrderDate AS 'OrderDate', 
soh.TotalDue AS 'TotalDue'
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
ORDER BY c.CustomerID
-- FOR XML PATH, instead of <row> element name the element <Invoice> 
FOR XML PATH('Invoice');

/* Results, showing an Invoice elemnent for each row

<Invoice CustID="11000" SalesID="43793">
  <PersonName>Yang</PersonName>
  <OrderDate>2011-06-21T00:00:00</OrderDate>
  <TotalDue>3756.9890</TotalDue>
</Invoice>
<Invoice CustID="11000" SalesID="51522">
  <PersonName>Yang</PersonName>
  <OrderDate>2013-06-20T00:00:00</OrderDate>
  <TotalDue>2587.8769</TotalDue>
</Invoice>
<Invoice CustID="11000" SalesID="57418">
  <PersonName>Yang</PersonName>
  <OrderDate>2013-10-03T00:00:00</OrderDate>
  <TotalDue>2770.2682</TotalDue>
</Invoice>

*/

-- you can also next elements within other elements by placing a nested subquery within your SELECT statement. Everything with an @ symbol will be returned as an attribute, and everything without an @ will be returned as an element. Apparently all of the attributes in a sibling grouping must be listed first, then the elements.
SELECT c.CustomerID AS '@CustID', 
c.LastName AS 'PersonName',
-- begins inner SELECT which will be nested under the overall <OuterQuery> element for each row definied in the outer FOR XML PATH statement. You can nest an element within another element by spelling it out in the XPath. In this case, the <customer> element will be enclosed in a <customers> element
(SELECT	FirstName AS 'customer/firstname',
		LastName AS 'customer/lastname'
		FROM Sales.customerpii AS c2
		WHERE c.CustomerID = c2.CustomerID
		-- inner FOR XML PATH,, with a blank so each customer isn't placed into its own element, placed within a root element of <customers>
		FOR XML PATH(''), ROOT('customers')),
soh.SalesOrderID AS 'SalesID', 
soh.OrderDate AS 'OrderDate', 
soh.TotalDue AS 'TotalDue'
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
WHERE c.CustomerID IN ( 19169, 17423, 22728)
ORDER BY c.CustomerID
-- the outer FOR XML PATH, each row will get an element <outerquery>, and it will all be encapslated in an <invoice> root element 
FOR XML PATH('OuterQuery'), ROOT('Invoice');

/* Results, showing an Invoice elemnent for each row. Note that it treats the results of the inner query as literals, so instead of '<' you'll get '&lt;' and instead of '>' you'll get '&gt;'
<Invoice>
  <OuterQuery CustID="17423">
    <PersonName>Alexander</PersonName>&lt;customers&gt;&lt;customer&gt;&lt;firstname&gt;Arianna&lt;/firstname&gt;&lt;lastname&gt;Alexander&lt;/lastname&gt;&lt;/customer&gt;&lt;/customers&gt;<SalesID>70717</SalesID><OrderDate>2014-04-15T00:00:00</OrderDate><TotalDue>2538.4944</TotalDue></OuterQuery>
  <OuterQuery CustID="19169">
    <PersonName>Bryant</PersonName>&lt;customers&gt;&lt;customer&gt;&lt;firstname&gt;Arianna&lt;/firstname&gt;&lt;lastname&gt;Bryant&lt;/lastname&gt;&lt;/customer&gt;&lt;/customers&gt;<SalesID>51657</SalesID><OrderDate>2013-06-27T00:00:00</OrderDate><TotalDue>1293.3804</TotalDue></OuterQuery>
  <OuterQuery CustID="22728">
    <PersonName>Russell</PersonName>&lt;customers&gt;&lt;customer&gt;&lt;firstname&gt;Arianna&lt;/firstname&gt;&lt;lastname&gt;Russell&lt;/lastname&gt;&lt;/customer&gt;&lt;/customers&gt;<SalesID>53264</SalesID><OrderDate>2013-07-27T00:00:00</OrderDate><TotalDue>165.6727</TotalDue></OuterQuery>
</Invoice>

To fix this, you can do a Find and Replace in SQL Server and replace '&lt;' with '<' and '&gt;' with '>', and you'll end up with normal XML code:

<Invoice>
  <OuterQuery CustID="17423">
    <PersonName>Alexander</PersonName>
	<customers>
		<customer>
			<firstname>Arianna</firstname>
			<lastname>Alexander</lastname>
		</customer>
	</customers>
	<SalesID>70717</SalesID>
	<OrderDate>2014-04-15T00:00:00</OrderDate>
	<TotalDue>2538.4944</TotalDue>
  </OuterQuery>
  <OuterQuery CustID="19169">
    <PersonName>Bryant</PersonName>
	<customers>
		<customer>
			<firstname>Arianna</firstname>
			<lastname>Bryant</lastname>
		</customer>
	</customers>
	<SalesID>51657</SalesID>
	<OrderDate>2013-06-27T00:00:00</OrderDate>
	<TotalDue>1293.3804</TotalDue>
  </OuterQuery>
  <OuterQuery CustID="22728">
    <PersonName>Russell</PersonName>
	<customers>
		<customer>
			<firstname>Arianna</firstname>
			<lastname>Russell</lastname>
		</customer>
	</customers>
	<SalesID>53264</SalesID>
	<OrderDate>2013-07-27T00:00:00</OrderDate>
	<TotalDue>165.6727</TotalDue>
  </OuterQuery>
</Invoice>
*/

-------------------
-- EXPLICIT MODE --
-------------------

-- EXPLICIT - based on a tabular representation of XML documents, and enables complete control over the XML structure. This allows you to mix and match it being attribute-centric AND element-centric. You can create multiple levels in the hierarchy by creating multiple SELECT satements and UNIONing them together (one SELECT statement per level in the hierarchy). Read up on this if you ever want to use this. Uses a very specific naming convention such as [Invoice!1!FName!Element].
SELECT 1 AS Tag, NULL AS Parent,
CustomerID AS [Invoice!1!CustID],
FirstName AS [Invoice!1!FName!Element], 
LastName AS [Invoice!1!LName!Element]
FROM sales.customerpii 
FOR XML EXPLICIT;

-- detail of the EXPLICIT example above

-- Tag sets the base attribute (?)
SELECT 1 AS Tag, NULL AS Parent,
-- naming convention, Invoice creates a base element, and CustID will be a child element underneath Invoice - this lacks the word Element, so this row will be created as an attribute in the XML
CustomerID AS [Invoice!1!CustID],
-- Element keyword used to create an element for this column
FirstName AS [Invoice!1!FName!Element], 
LastName AS [Invoice!1!LName!Element]
FROM sales.customerpii 
FOR XML EXPLICIT;

/* Results as XML, creating an Invoice element, placing CustID as an attribute, and creating FName and LName as child elements within Invoice

<Invoice CustID="19169">
  <FName>Arianna</FName>
  <LName>Bryant</LName>
</Invoice>
<Invoice CustID="17423">
  <FName>Arianna</FName>
  <LName>Alexander</LName>
</Invoice>
<Invoice CustID="17722">
  <FName>Jerome</FName>
  <LName>Serrano</LName>
</Invoice>
<Invoice CustID="22728">
  <FName>Arianna</FName>
  <LName>Russell</LName>
</Invoice>

*/

-----------------------------------
-- USING NAMESPACES WITH FOR XML --
-----------------------------------

-- you can define a namespace by adding WITH XMLNAMESPACES at the beginning of your query. Supported only for RAW, AUTO and PATH modes. An example is:
WITH XMLNAMESPACES ('http://aw/order' AS ord)

-- example of adding XML namespace using RAW mode. Note that you use the prefix 'ord' before each element to associate that element with the namespace you've prefixed 'ord' in the first line
WITH XMLNAMESPACES ('http://aw/order' AS ord)
SELECT c.CustomerID AS 'ord:CustID', c.LastName AS 'ord:PersonName',
soh.SalesOrderID, soh.OrderDate, soh.TotalDue
FROM sales.customerpii c
JOIN sales.salesorderheader soh
ON c.CustomerID = soh.CustomerID
ORDER BY c.CustomerID
FOR XML RAW('ord:order'), ELEMENTS;

/* Results, note that a namespace of 'http://aw/order', aliased 'ord', has been added to the Orders root element

<Orders xmlns:ord="http://aw/order">
  <ord:order>
    <ord:CustID>11000</ord:CustID>
    <ord:PersonName>Yang</ord:PersonName>
    <SalesOrderID>43793</SalesOrderID>
    <OrderDate>2011-06-21T00:00:00</OrderDate>
    <TotalDue>3756.9890</TotalDue>
  </ord:order>
  <ord:order>
    <ord:CustID>11000</ord:CustID>
    <ord:PersonName>Yang</ord:PersonName>
    <SalesOrderID>51522</SalesOrderID>
    <OrderDate>2013-06-20T00:00:00</OrderDate>
    <TotalDue>2587.8769</TotalDue>
  </ord:order>
...
*/

----------------------------------
-- PREVIOUS NOTES ABOUT FOR XML --
----------------------------------

SELECT TOP 5 playerID, teamID, HR FROM batting

/* Results from that basic query:

playerID      teamID   HR
------------  -------  ----
berrych02     PHA      0
bettshu01     BSN      0
birkora01     PIT      0
bishoma01     BOS      1
blaehge01     SLA      0

*/

-- FOR XML AUTO, which will take the results set and return it as XML - you specify the ROOT which will become the root element, and then it will create an element named after the table you are selecting from, and that element will be repeated for each row in the table, with the column values being added as attributes in each repeated element.
SELECT TOP 5 playerID, teamID, HR FROM batting
FOR XML AUTO, ROOT('Player_Stats');

/* Results:

<Player_Stats>
  <batting playerID="berrych02" teamID="PHA" HR="0" />
  <batting playerID="bettshu01" teamID="BSN" HR="0" />
  <batting playerID="birkora01" teamID="PIT" HR="0" />
  <batting playerID="bishoma01" teamID="BOS" HR="1" />
  <batting playerID="blaehge01" teamID="SLA" HR="0" />
</Player_Stats>

*/

-- you can also use FOR XML PATH, which allows you to determine what will columns will be listed as an XML attribute and which will be listed as an XML element. An element called row will be created for each row in the results set. If you select a column AS '@columnname' (with an @ sign surrounded by quotes), the column will be pulled as an attribute. If you do not include an @ sign before the column, it will be pulled as an element. In the example below, playerID and teamID will be pulled as attributes, and HR and RBI will be pulled as elements.
SELECT TOP 5 playerID AS '@playerID', teamID AS '@teamID', HR, RBI
FROM Batting 
FOR XML PATH, ROOT('Player_Stats');

/* Results:

<Player_Stats>
  <row playerID="berrych02" teamID="PHA">
    <HR>0</HR>
    <RBI>34</RBI>
  </row>
  <row playerID="bettshu01" teamID="BSN">
    <HR>0</HR>
    <RBI>2</RBI>
  </row>
  <row playerID="birkora01" teamID="PIT">
    <HR>0</HR>
    <RBI>11</RBI>
  </row>
  <row playerID="bishoma01" teamID="BOS">
    <HR>1</HR>
    <RBI>22</RBI>
  </row>
  <row playerID="blaehge01" teamID="SLA">
    <HR>0</HR>
    <RBI>2</RBI>
  </row>
</Player_Stats>

*/

-- using FOR XML PATH, you can also use a slash to contain your column elements within parent elements. Below, each row in the results set will be added as a row element with playerID as an attribute. The HR, Doubles, and RBI columns will be pulled as elements called HomeRuns, Doubles, and RunsBattedIn, and all three elements will be contained within a parent element BattingStats (since in the query the AS clause is preceded with BattingStats/ for each one). SB and CS will be pulled as the elements StolenBases and CaughtStealing, and since they are both preceded by RunningStats/, those elements will be contained within the parent element RunningStats. 
SELECT TOP 3 playerID AS '@playerID',
HR AS 'BattingStats/HomeRuns',
Doubles AS 'BattingStats/Doubles',
RBI AS 'BattingStats/RunsBattedIn',
SB AS 'RunningStats/StolenBases',
CS AS 'RunningStats/CaughtStealing'
FROM Batting
FOR XML PATH, ROOT('Player_Stats');

/* Results:

<Player_Stats>
  <row playerID="berrych02">
    <BattingStats>
      <HomeRuns>0</HomeRuns>
      <Doubles>10</Doubles>
      <RunsBattedIn>34</RunsBattedIn>
    </BattingStats>
    <RunningStats>
      <StolenBases>1</StolenBases>
      <CaughtStealing>0</CaughtStealing>
    </RunningStats>
  </row>
  <row playerID="bettshu01">
    <BattingStats>
      <HomeRuns>0</HomeRuns>
      <Doubles>1</Doubles>
      <RunsBattedIn>2</RunsBattedIn>
    </BattingStats>
    <RunningStats>
      <StolenBases>0</StolenBases>
      <CaughtStealing>0</CaughtStealing>
    </RunningStats>
  </row>
  <row playerID="birkora01">
    <BattingStats>
      <HomeRuns>0</HomeRuns>
      <Doubles>3</Doubles>
      <RunsBattedIn>11</RunsBattedIn>
    </BattingStats>
    <RunningStats>
      <StolenBases>0</StolenBases>
      <CaughtStealing>0</CaughtStealing>
    </RunningStats>
  </row>
</Player_Stats>

*/

以上是关于FOR XML PATH('')),1,1,'')这是啥意思的主要内容,如果未能解决你的问题,请参考以下文章

关于for xml path('')

将SQL for xml path('')中转义的字符正常显示

求教oracle中类似mysql中for xml path('')的功能

SQL - for xml path('') 实现多行合并到一行, 并带有分隔符

合并多行查询数据到一行:使用自连接FOR XML PATH('')STUFF或REPLACE函数

sql server 2000中如何使用xml for path来进行字符串拼接