【问题标题】:Converting DataSet into XML with nested elements使用嵌套元素将 DataSet 转换为 XML
【发布时间】:2011-07-27 19:45:57
【问题描述】:

我正在编写一个应该将 DataSet 转换为 XML 的 WebService。我的数据集实际上是带有类别的酒店列表。每个酒店可以属于一个或多个类别。 我遵循了来自 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 - 表 Category 中的酒店 ID(外键)

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

【问题讨论】:

    标签: c# xml web-services dataset nested


    【解决方案1】:

    1) 这真的重要吗?一种结构比另一种更好吗?

    是的,如果您将类别 ID 添加到类别输出中,那么很容易推断出哪个 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】:

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

      什么更好?如果您希望能够将数据读回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 的序列化格式定义非常严格。它支持几个选项(嵌套,包括模式、差异图),但格式不会改变(除非您保存为差异图,但如果您这样做,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>
      

      【讨论】:

      • 更多拉风格&lt;xsl:template match="category"/&gt; &lt;xsl:template match="category[1]"&gt; &lt;categories&gt; &lt;xsl:apply-templates select="../category/*"/&gt; &lt;/categories&gt; &lt;/xsl:template&gt;
      【解决方案3】:

      您可以编写一个 sql 来生成所需的模型,直接从数据库中以 xml 格式生成,例如...

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

      当然取决于您的数据库布局...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多