将结构XML转换为平面XML,但某些列除外

时间:2014-03-05 09:34:09

标签: c# xml sqlite

我已经导出一个SQLite数据库来构造XML,然后使用c#.net中的以下代码将其转换为扁平XML。

XDocument Doc = XDocument.Load("myXML.xml");
            XElement[] elements = Doc.DescendantNodes()
                .Where(n => n.NodeType == XmlNodeType.Text).Select(n => n.Parent).ToArray(); 

            foreach (XElement element in elements)
            {
                element.Parent.SetAttributeValue(element.Name, element.Value);
                element.Remove();
            }

结构XML如下所示

<apple>
      <id>1</id>
      <name>Apple 1</name>
      <orange>
        <id>5</id>
        <orangeNmae>C1</orangeNmae>
        <function>good for health</function>
        <part>7</part>
        <banana>
          <id>9</id>
          <bananaName>48</bananaName>
          <effect>23</effect>         
          <notes>be careful</notes>
        </banana>
        <banana>
          <id>10</id>
          <bananaName>49</bananaName>
          <effect>24</effect>         
          <notes>be careful!</notes>        
        </banana>
      </orange>
</apple>

生成的扁平xml如下所示

<apple id="1" name="Apple 1">
      <orange id="5" orangeNmae="C1" function="good for health" part="7">        
        <banana id="9" bananaName="48" effect="23" notes="be careful" />
        <banana id="10" bananaName="49" effect="24" notes="be careful" />        
      </orange>
</apple>

现在我需要保留像结构化XML这样的列,如下面的

<apple id="1" name="Apple 1">
      <orange id="5" orangeNmae="C1" function="good for health" part="7">        
        <banana id="9" bananaName="48" />               
          <notes>be careful</notes>
          <effect>23</effect>
        <banana id="10" bananaName="49" />                   
          <notes>be careful</notes>
          <effect>23</effect>       
      </orange>
</apple>

有人能给我任何提示怎么做吗? 我应该在将结构化XML转换为扁平XML时改变我的方法吗?

1 个答案:

答案 0 :(得分:0)

此XSLT为您完成转换。我使用模板来匹配元素,并使用XSLT处理器的模式功能来首先处理属性的transdormation,然后处理其他元素。

  <!-- elements to be transformed to attributes -->
  <xsl:template match="*[not(text()[normalize-space()])]">
    <xsl:element name="{name()}">
      <xsl:apply-templates mode="attr"/>
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>

  <!-- copy elements not handled as attribute -->
  <xsl:template match="effect|notes">
    <xsl:copy-of select="."/>
  </xsl:template>

  <!-- create attributes excluding certain elements -->
  <xsl:template match="*[text()[normalize-space()] and not(self::effect | self::notes)]" mode="attr">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="./text()"/>
    </xsl:attribute>
  </xsl:template>

  <!-- surpress defaults -->
  <xsl:template match="text()">
  </xsl:template>
  <xsl:template match="*|text()" mode="attr">
  </xsl:template>

以下是你如何利用它:

        var xct = new XslCompiledTransform();
        xct.Load(XmlReader.Create("transform.xslt"));
        var xw = XmlWriter.Create("output.xml"));
        xct.Transform(
           XmlReader.Create("input.xml"),
           xw);