如何根据节点数量将一个XML文件拆分为多个XML文件
本文关键字:XML 文件 一个 拆分 节点 何根 | 更新日期: 2023-09-27 18:15:44
这个问题与这个问题非常相似,但有一点不同。
我试图根据每个对象允许的标记元素的数量将表示xml的对象分割为多个xml对象。我在尝试找到最好的解决方法。任何帮助都会很好…关于我正在尝试做什么的示例示例…
xml源表示:
<?xml version="1.0" encoding="utf-8"?>
<DocType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pmlcore="urn:autoid:specification:interchange:xml:schema:1">
<id>tbd</id>
<Observation>
<Command>c1</Command>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Data>...</Data>
</Observation>
<Observation>
<Command>c2</Command>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Data>...</Data>
</Observation>
</DocType>
给定每个文档允许的'标签'元素数量的期望输出是…3
xml 1:<?xml version="1.0" encoding="utf-8"?>
<DocType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pmlcore="urn:autoid:specification:interchange:xml:schema:1">
<id>tbd</id>
<Observation>
<Command>c1</Command>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Data>...</Data>
</Observation>
</DocType>
xml 2: <?xml version="1.0" encoding="utf-8"?>
<DocType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pmlcore="urn:autoid:specification:interchange:xml:schema:1">
<id>tbd</id>
<Observation>
<Command>c1</Command>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Data>...</Data>
</Observation>
<Observation>
<Command>c2</Command>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Data>...</Data>
</Observation>
</DocType>
我相信现在你已经知道要求是什么了,但我将继续:
xml 3:<?xml version="1.0" encoding="utf-8"?>
<DocType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pmlcore="urn:autoid:specification:interchange:xml:schema:1">
<id>tbd</id>
<Observation>
<Command>c2</Command>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Data>...</Data>
</Observation>
</DocType>
xml 4: <?xml version="1.0" encoding="utf-8"?>
<DocType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pmlcore="urn:autoid:specification:interchange:xml:schema:1">
<id>tbd</id>
<Observation>
<Command>c2</Command>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Tag>
<id>....</id>
<Data>...</Data>
</Tag>
<Data>...</Data>
</Observation>
</DocType>
XSLT 2.0(由Saxon https://www.nuget.org/packages/Saxon-HE/支持)允许您将一个XML文档转换为多个文档,下面是将输入拆分为多个文件的一种方法:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:param name="tags-per-doc" as="xs:integer" select="3"/>
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:for-each-group select="//Tag" group-adjacent="(position() - 1) idiv $tags-per-doc">
<xsl:result-document href="result{position()}.xml">
<xsl:apply-templates select="/*"/>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Observation">
<xsl:if test="current-group() intersect *">
<xsl:copy>
<xsl:apply-templates select="@*, node()[. intersect current-group() or not(self::Tag)]"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
您需要加载初始文档,然后从文档中删除Observation
标记。循环Observation标记并创建新文档,在其中添加Observation
标记项。在docList中,您拥有所有新文档。
var result = doc.Root.Elements().Where(x => x.Name == "Observation").ToList();
doc.Root.Elements().Where(x => x.Name == "Observation").Remove();
List<XDocument> docList = new List<XDocument>();
foreach(var el in result)
{
XDocument d = new XDocument(doc);
d.Root.Add(el);
docList.Add(d);
}
我认为你最好的选择是为你的数据建立一个模型。
public class Observation
{
public string Command { get; set; }
public List<Tag> Tags { get; set; }
}
[...] // Define also de Tag class
然后你可以很容易地用LINQ to xml读取xml,用你想要的标准处理模型,并使用LINQ to xml保存它。
我真的觉得学习如何使用LINQ到XML已经超出了问题的范围,所以我要你参考另一个问题来处理它:使用LINQ to xml解析xml到类对象
并且,请尽量不要直接使用数据作为原始行,然后再次保存它,在此之后您想要进行的任何更改都将是一场噩梦。