简体   繁体   English

使用LINQ从xml读取CDATA不会返回预期结果

[英]Read CDATA from xml using LINQ not returning expected result

I am trying to read the "query" element value (which is defined as CDATA) within an xml file using LINQ, however, when I run the application I am being returned the following value: 我正在尝试使用LINQ在xml文件中读取“查询”元素值(定义为CDATA),但是,当我运行该应用程序时,将返回以下值:

System.Linq.Enumerable+WhereSelectEnumerableIterator`2[System.Xml.Linq.XElement,System.String] System.Linq.Enumerable + WhereSelectEnumerableIterator`2 [System.Xml.Linq.XElement,System.String]

I am confused as to what I am missing to get the CDATA value. 我对于获得CDATA值缺少什么感到困惑。

The XML document looks like this: XML文档如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<dbprocedurestruct>
  <variables id="vars">
    <variable id="ooid">
      <name>OrigOrgID</name>
      <pseudo>Original Organization ID</pseudo>
      <type>System.Int32</type>
      <visible>true</visible>
    </variable>
    <variable id="noid">
      <name>NewOrgID</name>
      <pseudo>New Organization(s) ID</pseudo>
      <type>System.Int32</type>
      <visible>true</visible>
    </variable>
    <variable id="nssid">
      <name>NewSysSubID</name>
      <pseudo>New System Subscription ID</pseudo>
      <type>System.Int32</type>
      <visible>false</visible>
    </variable>
  </variables>
  <scripts>
    <script name="createscript">
      <query>
        <![CDATA[
        SELECT 
        SystemSubscriptionID, 
        'INSERT INTO dbo.Subscriptions 
        (
        SubscriptionID, 
        SystemSubscriptionTierID, 
        IsCustomized, 
        SubscriptionPrice, 
        DownloadPrice, 
        PlansPrice, 
        SpecsPrice, 
        SubscriptionStartDate, 
        SubscriptionDuration, 
        AutoRenewSubscription, 
        IsActive, 
        SubscriptionStatus, 
        CreatedBy, 
        CreatedOn, 
        LastEditBy, 
        LastEditOn)
        VALUES (' + 
        CAST(SubscriptionID AS VARCHAR(50)) + ',' + 
        CAST(SystemSubscriptionTierID AS VARCHAR(50)) + ',' +
        CAST(IsCustomized AS VARCHAR(50)) + ',' + 
        CAST(SubscriptionPrice AS VARCHAR(50)) + ',' + 
        CAST(DownloadPrice AS VARCHAR(50)) + ',' + 
        CAST(PlansPrice AS VARCHAR(50)) + ',' + 
        CAST(SpecsPrice AS VARCHAR(50)) + ',''' + 
        CAST(GetDate() AS VARCHAR(50)) + ''',' + 
        CAST(SubscriptionDuration AS VARCHAR(50)) + ',' + 
        CAST(AutoRenewSubscription AS VARCHAR(50)) + ',' + 
        CAST(IsActive AS VARCHAR(50)) + ',' + 
        CAST(SubscriptionStatus AS VARCHAR(50)) + ', 2, ''' + 
        CAST(GetDate() AS VARCHAR(50)) + ''', 2, ''' + 
        CAST(GetDate() AS VARCHAR(50)) + ''') '  
        FROM Subscriptions WHERE SystemSubscriptionID IN 
        (SELECT SystemSubscriptionID FROM SubscriptionMappings WHERE ReferenceID = {0});
        SELECT IDENT_CURRENT('Subscriptions')
        ]]>
      </query>
    </script>
    <script name="mappingscript">
      <query>
        <![CDATA[
        INSERT INTO SubscriptionMappings 
        (SystemSubscriptionID,
        ReferenceID,
        SubscriptionTypeID,
        SystemId,
        IsActive,
        CreatedBy) 
        SELECT 
        {0},
        {1},
        CAST(SubscriptionTypeID AS VARCHAR(50)),
        2,
        CAST(IsActive AS VARCHAR(50)),
        2 FROM SubscriptionMappings 
        WHERE ReferenceID = {2} 
        AND 
        SystemSubscriptionID = {3}
        ]]>
      </query>
    </script>
  </scripts>
</dbprocedurestruct>

Here is my snippet of code that reads the xml file: 这是我读取xml文件的代码片段:

    SQLConnectivity _sc = new SQLConnectivity();
    DataTable dt = new DataTable();
    string xmlitem = (from scripts in xfile.Descendants("scripts") where scripts.Element("script").Value == "createscript" select scripts.Element("script").Element("query").Value).ToString();
    //String tempquery = xmlitem.Elements("query").ToString();
    String finalquery = String.Format(xmlitem, _ooid);

    _sc.RunExecuteSQL(finalquery, ref dt);
    return dt;

The result of the query is an IEnumerable instance. 查询的结果是IEnumerable实例。 If you want a single string result then you'll need to use either FirstOrDefault or SingleOrDefault . 如果需要单个字符串结果,则需要使用FirstOrDefaultSingleOrDefault Also, you need to use the "name" attribute when searching for the designated "createscript" element. 另外,搜索指定的“ createscript”元素时,需要使用“ name”属性。

var sql = (from scripts in xfile.Root.Elements("scripts")
           from script in scripts.Elements("script")
           let name = script.Attribute("name")
           where name != null && name.Value == "createscript"
           from query in script.Elements("query")
           select query.Value).FirstOrDefault();

Edit: Leading and trailing carriage returns and indentation can be stripped from the SQL with a combination of string.Trim and Regex.Replace . 编辑:可以使用string.TrimRegex.Replace的组合从SQL剥离开头和结尾的回车符和缩进。

var cleanSql = Regex.Replace(sql.Trim(), @"^\s+", "", RegexOptions.Multiline);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM