【问题标题】:Remove xsi nil through regex通过正则表达式删除 xsi nil
【发布时间】:2012-06-03 22:00:09
【问题描述】:

我有一个生成序列化 xml 的第三方组件和解析 xml 并将值插入表的存储过程。

我在组件和 sql 存储过程中处理 xsi nil 时遇到问题。我无法控制更改组件或存储过程。所以属性解决方案上的 IsNullable 属性而不是过程解决方案上的 xsi=true 对我没有帮助。

我正在尝试使用正则表达式来处理这个问题。

.*xsi\:nil\=\"true\" \/\>

上面的正则表达式匹配非常适合下面的输入

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<prop1>
    <prop11>abc</prop11>
    <prop12 xsi:nil="true" />
    <prop13>def</prop13>
</prop1>
</Root>

但不适用于此输入

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><prop1><prop11>abc</prop11><prop12 xsi:nil="true" /><prop13>def</prop13></prop1></Root>

想要的输出是

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<prop1>
    <prop11>abc</prop11>
    <prop13>def</prop13>
</prop1>
</Root>

更新: 属性名称和级别仅在运行时已知。请参考下面的不同xml

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<pa>
    <paa>abc</paa>
    <pab xsi:nil="true" />
    <pac>def</pac>
            <pad>
               <pada>val1</pada>
               <padb xsi:nil="true" />
               <padc>
                     <padca>vala</padca>
                     <padcb xsi:nil="true" />
               </padc>
            <pad>
</prop1>
</Root>

上述 xml 的期望输出是

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<pa>
    <paa>abc</paa>
    <pac>def</pac>
            <pad>
               <pada>val1</pada>
               <padc>
                     <padca>vala</padca>
               </padc>
            <pad>
</prop1>
</Root>

谁能帮帮我

谢谢,

埃森

【问题讨论】:

  • 您要替换值吗?用什么? IE,想要的结果是什么?
  • 用空字符串替换它
  • 调整我的答案给你想要的结果。

标签: c# .net xml regex


【解决方案1】:

使用此库中的 XPath:https://github.com/ChuckSavage/XmlLib/

我得到了具有xsi:nil=true 的 XElements:

XElement root = XElement.Load(file);
// or root = XElement.Parse(xml);
IEnumerable<XElement> result = root.XPath("//*[@xsi:nil={0}]", true);
result.ToList().ForEach(x => x.Remove());
root.Save(file);
// or xml = root.ToString();

我用这个 XML 对其进行了测试:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <prop1>
    <prop10 xsi:nil="true" />
    <prop11>abc</prop11>
    <prop12 xsi:nil="true" />
    <prop13>def</prop13>
    <prop14 xsi:nil="true" />
    <prop15>def</prop15>
    <prop16 xsi:nil="true" />
  </prop1>
</Root>

并找到所有 4 个 XElement。从那里他们被删除。

生成的 XML 是:

<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <prop1>
    <prop11>abc</prop11>
    <prop13>def</prop13>
    <prop15>def</prop15>
  </prop1>
</Root>

如果您不关心 xsi:nil 是否为真,并且您只想删除带有 xsi:nil 属性的所有节点,您可以将 XPath 框起来,如下所示:

IEnumerable<XElement> result = root.XPath("//*[@xsi:nil]");

【讨论】:

  • 谢谢chuck,是否可以使其通用。因为我不知道属性名称。并且持有空值的属性级别也是未知的。请参考我的第二个例子
【解决方案2】:

使用 Linq to XML

using System.Xml.Linq;

        var f = XDocument.Load("c:\\01.xml");
        var xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
        var nills = from n in f.Root.Elements("prop1").Elements()
                    where n.Attribute(xsi + "nil") != null
                    select n;

        nills.ToList().ForEach(x => x.RemoveAttributes());

        f.Save("c:\\011.xml");

这产生了以下结果:

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <prop1>
    <prop11>abc</prop11>
    <prop12 />
    <prop13>def</prop13>
  </prop1>
</Root>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 2019-02-16
    • 2013-06-25
    相关资源
    最近更新 更多