【问题标题】:Delete all empty nodes from XML in SQL Server从 SQL Server 中的 XML 中删除所有空节点
【发布时间】:2019-01-07 15:44:37
【问题描述】:

我想删除 XML 文件中的所有空节点。即使节点以

的形式存在
<Node/>    OR    <Node></Node>

节点应该从 XML 中删除。

<Root type="1">
<A></A>
<B>
    <B1>
        <B12/>
        <B13/>
    </B1>
    <B2>
        123
        <B21></B21>
    </B2>
   <B3 type="3">
       <B4/>
   </B3>
</B>
<C/>
</Root>

预期输出:

<Root type="1">
<B>
    <B2>
        123
    </B2>
    <B3 type="3">
    </B3>
</B>
</Root>

删除B1节点,因为B1下的所有节点都是空的,也没有属性。

不要删除 B2 因为 B2 的值为 123 ,但要删除它的空子节点。

不要删除 B3,因为 B3 有一个属性,而是删除它的空子节点。

我正在使用 SQL 来做同样的事情,但如果这也可以在 c# 中完成,我可以从 SSIS 调用 C# 脚本,但首选 SQL。

【问题讨论】:

    标签: c# sql sql-server xml xml-parsing


    【解决方案1】:

    用正则表达式就可以轻松搞定:

    string xml = @"<Root type=""1"">
                    < A ></ A >
                    < B >
                        < B1 >
                            < B12 />
                            < B13 />
                        </ B1 >
                        < B2 >
                            123
                            < B21 ></ B21 >
                        </ B2 >
                       < B3 type = ""3"" >
    
                            < B4 />
    
                        </ B3 >
                     </ B >
                     < C />
                     </ Root > ";
    
    
    xml = Regex.Replace(xml, @"<.+?/>", "");
    xml = Regex.Replace(xml, @"<(.+?)>\s*</\1>", "");
    

    【讨论】:

    • 是否需要将所有“”替换为“”?
    • 是的,因为单 " 会终止字符串,所以在字符串中你需要使用双 "
    【解决方案2】:

    在 C# 中的一种方法是:

    var x = XElement.Parse(@"<Root type=""1"">
                                <A></A>
                                <B>
                                    <B1>
                                        <B12/>
                                        <B13/>
                                    </B1>
                                    <B2>
                                        123
                                        <B21></B21>
                                    </B2>
                                   <B3 type=""3"">
                                       <B4/>
                                   </B3>
                                </B>
                                <C/>
                                </Root>");
    
    foreach(XElement child in x.Descendants().Reverse())
    {
        if(!child.HasElements && string.IsNullOrEmpty(child.Value) && !child.HasAttributes) 
            child.Remove();
    }
    

    【讨论】:

    • 是否需要将所有“”替换为“”?
    • @KMittal 是的。 .
    【解决方案3】:

    在 SQL Server 中执行此操作的最简单方法。

    SET @xml.modify('
    
    delete //*[not(node()) and not(./@*)]
    
    ');
    
    SELECT @xml.query('//*[not(node()) and not(./@*)]') 
    
    SET @xml.modify('
    
    delete //*[not(node()) and not(./@*)]
    
    ');
    
    SELECT @xml.query('//*[not(node()) and not(./@*)]') 
    
    SET @xml.modify('
    
    delete //*[not(node()) and not(./@*)]
    
    ');
    
    SELECT @xml.query('//*[not(node()) and not(./@*)]') 
    
    SET @xml.modify('
    
    delete //*[not(node()) and not(./@*)]
    
    ');
    
    SELECT @xml.query('//*[not(node()) and not(./@*)]') 
    

    我还可以选择我忽略/删除的所有节点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-23
      • 1970-01-01
      • 2023-03-23
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多