2011-04-01 61 views
1

我正在编写一个应该将DataSet转换为XML的WebService。我的数据集实际上是具有类别的酒店列表。每家酒店可以属于一个或多个类别。 我跟着HERE的一个例子,它运作良好,除非我没有得到我想要的结果。使用嵌套元素将DataSet转换为XML

这就是我得到:(例1)

<hotels> 
    <hotel> 
     <name>Hilton Resort</name> 
     <category> 
      <catname>Hotel</catname> 
     </category> 
     <category> 
      <catname>Resort</catname> 
     </category> 
     <category> 
      <catname>Golf & Spa</catname> 
     </category> 
    </hotel> 
    <hotel> 
     <name>Hyatt</name> 
     <category> 
      <catname>Resort</catname> 
     </category> 
     <category> 
      <catname>Golf & Spa</catname> 
     </category> 
    </hotel> 
</hotel> 

,但是,我希望得到的东西是这样的:(例如2)

<hotels> 
    <hotel> 
     <name>Hilton Resort</name> 
     <categories> 
      <catname>Hotel</catname> 
      <catname>Resort</catname> 
      <catname>Golf & Spa</catname> 
     </categories> 
    </hotel> 
    <hotel> 
     <name>Hyatt</name> 
     <categories> 
      <catname>Hotel</catname> 
      <catname>Golf & Spa</catname> 
     </categories> 
    </hotel> 
</hotel> 

这里是产生我当前的代码XML作为例子1:

 ... 
     ... 
     SqlDataAdapter hotelDA = new SqlDataAdapter(SQLHotels, SQLConn); 
     SqlDataAdapter catDA = new SqlDataAdapter(SQLCats, SQLConn); 

     DataSet ds = new DataSet("Hotels"); 

     hotelDA.Fill(ds, "Hotel"); 
     catDA.Fill(ds, "Category"); 

     DataRelation SleepRel = ds.Relations.Add("Hotel", 
       ds.Tables["Sleep"].Columns["Id"], 
       ds.Tables["Category"].Columns["AccID"]); 
     SleepRel.Nested = true; 
     SQLConn.Close(); 
     return ds; 

SQLHotels - SQL SELECT选择所有类别
标识 SQL SELECT语句 - - 选择所有酒店
SQLCats声明酒店ID
ACCID - 酒店ID表类别(外键)

我的问题:
1)它确实重要吗?一个结构好于另一个结构吗?
2)是否有可能在DataSet中的两个表之间建立关系,这样我得到的输出就像在第二个(所需的)XML示例中一样。

回答

3

一种结构比另一种结构更好吗?

更好的是什么?如果你想能够将数据读回到DataSet,那么DataSet的格式非常好,所以按照这个标准,至少它比你提出的要好。

一般来说,当您处理XML文档时,您将使用XPath或Linq在其中搜索要使用的元素。比较:

var categories = hotelElement.SelectNodes("category"); 
var categories = hotelXElement.Elements("category"); 

有:

var categories = hotelElement.SelectNodes("categories/category"); 
var categories = hotelXElement.Elements("categories").Element("category"); 

是什么具有中间categories元素帮你吗? XML在编辑器中看起来好一点。这通常不是一个有吸引力的优势,特别是如果它使XML有点难以处理。

是否有可能在DataSet中的两个表之间建立关系,这样我得到的输出就像在第二个(期望的)XML示例中一样。

不。DataSet的序列化格式非常严格地定义。它支持一些选项(嵌套,包括模式,diffgrams),但格式不会改变(除非你保存为diffgrams,但如果你这样做了,那么XML在你的需求清单中看起来非常低)。

不过,您可以使用XSLT更改格式。这增加了identity transform

<xsl:template match="hotel"> 
    <xsl:apply-templates select="*[name() != 'category']"/> 
    <xsl:if test="category"> 
     <categories> 
     <xsl:apply-templates select="category"/> 
     </categories> 
    </xsl:if> 
</xsl:template> 
+0

很好的解释。谢谢 – bobetko 2011-04-01 19:41:37

+1

更多拉风格'' – 2011-04-07 03:54:36

+0

是的,这显然更好。 – 2011-04-07 18:03:33

0

1)它确实重要吗?一个结构好于另一个结构吗?

是,如果你添加的类别ID为cateogry输出,那么它很容易推理什么标识与哪个名字

<category> 
    <catId>1<cateId> 
    <catname>Hotel</catname> 
</category> 
<category> 
    <catId>2<cateId> 
    <catname>Resort</catname> 
</category> 
<category> 
    <catId>3<cateId> 
    <catname>Golf & Spa</catname> 
</category> 

这在另一方面是很难理性哪个ID与哪个因为协会是位置的。

<categories> 
    <catId>1<cateId> 
    <catname>Hotel</catname> 
    <catId>2<cateId> 
    <catname>Resort</catname> 
    <catId>3<cateId> 
    <catname>Golf & Spa</catname> 
</categories> 

2)是否有可能使在数据集的两个表之间的关系,所以我得到输出像它是在第二(期望的)XML实例。

有很多方法可以实现这一点(linq to dataset,XSLT等),但我想不出一种直接的方法。

0

你可以写,将直接从数据库中,像生产所需的模型,以XML格式的SQL ...

SELECT HotelName, 
     (select CategoryName from HotelCategories 
     where CategoryHotelName=HotelName 
     for xml path('Category')) as Categories 
FROM Hotels 
for xml path('Hotels') 

Ofcourse取决于您的数据库布局...