我正在编写一个应该将DataSet转换为XML的WebService。我的DataSet实际上是带有类别的酒店列表。每个酒店可以属于一个或多个类别。 我跟着HERE的一个例子,除了我没有得到我想要的结果外,它运作良好。
这就是我得到的:(示例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语句
SQLCats - 选择所有类别的SQL SELECT语句
ID - 酒店ID
AccId - 表格类别(外键)中的酒店ID
我的问题:
1)它真的重要吗?一个结构比另一个更好吗?
2)是否可以在DataSet中的两个表之间建立关系,因此我得到的输出就像它在第二个(所需的)XML示例中一样。
答案 0 :(得分:3)
一个结构比另一个好吗?
更好的是什么? DataSet
的格式非常好,如果您希望能够将数据读回DataSet
,那么按照该标准,至少,它优于您提议的那个。< / p>
一般来说,当您处理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>
答案 1 :(得分:0)
1)它真的重要吗?一个结构比另一个更好吗?
是的,如果您将类别ID添加到cateogry输出中,那么很容易说明Id与哪个名称相关
<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)是否可以在DataSet中的两个表之间建立关系,因此我得到的输出就像它在第二个(所需的)XML示例中一样。
你采取了很多方法来实现这一目标,(linq to dataset,XSLT等),但我无法想到一个直接的方法。
答案 2 :(得分:0)
您可以编写一个直接从数据库生成所需模型的sql,格式为xml格式,如...
SELECT HotelName,
(select CategoryName from HotelCategories
where CategoryHotelName=HotelName
for xml path('Category')) as Categories
FROM Hotels
for xml path('Hotels')
当然取决于您的数据库布局......