[英]How to Split an XML file into multiple XML Files based on number of nodes
這個問題是非常相似, 這一個 ,但有一小搓。
我試圖根據每個對象允許的標記元素的數量將表示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>
給定每個文檔允許的“ Tag ”元素數量的輸出是... 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>
您需要加載初始文檔,然后從文檔中刪除Observation
標記。 Loop 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 to XML超出了問題的范圍,所以我指的是另一個處理它的問題: 使用LINQ to XML將xml解析為類對象
並且請盡量不要將數據直接用作原始行然后再次保存,之后要進行的任何更改都將成為一場噩夢。
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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.