c# - 如何转换 XDocument 只留下选定的路径?
问题描述
我有很多(数百万)xml 文档,从小到大。我需要通过 c#7 处理(转换)它们,只留下一些路径(路径可能会有所不同;它们将由用户设置)。
一份文件的样本(我现在不关心命名空间):
<root>
<a><aa1></aa1><aa2></aa2></a>
<b><bb></bb></b>
<c><cc></cc></c>
<d>d</d>
</root>
给定/root/a/aa1
并且/root/d
被列入白名单我应该产生这个结果:
<root>
<a><aa1></aa1></a>
<d>d</d>
</root>
我想最好的方法是将白名单路径指定为 XPath 表达式的集合。
现有处理将 xml 加载到 XDocument 中。
我可以通过 选择必要的元素XPathSelectElements
。问题是:如何将它们复制到新的 XDocument 中?
或者,我可以删除所选元素的所有兄弟姐妹。如何执行该删除?
应考虑性能和内存占用。
解决方案
尝试以下算法:
(a) 扩展给定的路径集以包括这些路径的所有前缀,因此从 ( /root/a/aa1
, /root/d
) 你得到 ( /root
, /root/a
, /root/a/aa1
, /root/d
)
(b) 从这组路径生成一个 XSLT 样式表,其中 (i) 默认模板规则执行深度跳过 ( <xsl:template match="*"/>
),并且 (ii) 每个给定路径的模板规则执行浅拷贝 ( <xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
)。
(c) 在源文档上运行这个生成的样式表。
您可能会发现在 XPath 3.1/XSLT 3.0 中可以使用 EQName 表示法来处理命名空间敏感路径很有用,例如 match="Q{some-uri}root/Q{some-uri}a"。对于早期的 XPath 版本,处理引用命名空间元素名称的路径总是一个问题。这同样适用于非 XSLT 解决方案。
推荐阅读
- angular - Angular仅在材料数据表已满时如何调用子组件功能?
- vb.net - 参考/扩展/NuGet Pacakge VB.NET 之间的区别
- javascript - 带有自定义图标的传单标记示例 - 未触发 Microsoft Edge 的左键单击事件
- javascript - 在 Docker 中启动时初始化 MongoDB
- templates - 气流 - 在 KubernetesPodOperator 中动态更改命名空间
- python - 使用python获取列表附带的数据?
- reactjs - 如何使用 React json 模式中的对象自动生成的“表单组字段字段对象”类删除 divi
- flutter - 在 Timer 内部调用 setState 会导致 Flutter 内存泄漏?
- swift - 快速计算结构中的非空实例
- javascript - 获取后页面自动刷新,在 PHP 中使用“move_uploaded-file()”方法时