【问题标题】:How to Split an XML file into multiple XML Files based on number of nodes如何根据节点数将 XML 文件拆分为多个 XML 文件
【发布时间】:2017-03-14 17:51:17
【问题描述】:

这个问题与this one 非常相似,但略有不同。

我正在尝试根据每个对象允许的标记元素数将表示 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>

【问题讨论】:

  • 我真的不明白你在问什么。您提到您希望输出最多三个元素,但源只有两个,而您正在输出一个。
  • @JCabello 我已经编辑了问题以消除误解,希望现在清楚

标签: c# .net xml xml-parsing linq-to-xml


【解决方案1】:

我认为你最好的选择是为你拥有的数据建立一个模型。

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 超出了问题的范围,所以我向您推荐另一个处理它的问题: Parse xml using LINQ to XML to class objects

请尽量不要将数据直接用作原始行然后再次保存,之后您想要进行的任何更改都将是一场噩梦。

【讨论】:

    【解决方案2】:

    您需要加载初始文档,然后从文档中删除 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);
            }
    

    【讨论】:

      【解决方案3】:

      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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多