【问题标题】:XML parsing and transforming (XSLT or otherwise)XML 解析和转换(XSLT 或其他)
【发布时间】:2012-06-07 13:53:02
【问题描述】:

我有几个这样格式化的 xml 文件:

<ROOT>
  <OBJECT>
    <identity>
        <id>123</id>
    </identity>     
    <child2 attr = "aa">32</child2>
    <child3>
        <childOfChild3 att1="aaa" att2="bbb" att3="CCC">LN</childOfChild3>
    </child3>
    <child4>
        <child5>
            <child6>3ddf</child6>
            <child7>
                <childOfChild7 att31="RR">1231</childOfChild7>
            </child7>
        </child5>
    </child4>
  </OBJECT>
  <OBJECT>
    <identity>
        <id>124</id>
    </identity>     
    <child2 attr = "bb">212</child2>
    <child3>
        <childOfChild3 att1="ee" att2="ccc" att3="EREA">OP</childOfChild3>
    </child3>
    <child4>
        <child5>
            <child6>213r</child6>
            <child7>
                <childOfChild7 att31="EE">1233</childOfChild7>
            </child7>
        </child5>
    </child4>
  </OBJECT>
</ROOT>

我怎样才能这样格式化?:

<ROOT>
    <OBJECT>    
        <id>123</id>
        <child2>32</child2> 
        <attr>aa</attr>
        <child3></child3>
        <childOfChild3>LN</childOfChild3>
        <att1>aaa</att1>
        <att2>bbb</att2>
        <att3>CCC</att3>
        <child4></child4>
        <child5></child5>
        <child6>3ddf</child6>
        <child7></child7>
        <childOfChild7>1231</childOfChild7>
        <att31>RR</att31>
    </OBJECT>
        <OBJECT>    
        <id>124</id>
        <child2>212</child2>    
        <attr>bb</attr>
        <child3></child3>
        <childOfChild3>LN</childOfChild3>
        <att1>ee</att1>
        <att2>ccc</att2>
        <att3>EREA</att3>
        <child4></child4>
        <child5></child5>
        <child6>213r</child6>
        <child7></child7>
        <childOfChild7>1233</childOfChild7>
        <att31>EE</att31>
    </OBJECT>   
</ROOT>

我知道一些 C#,所以也许那里有一个解析器?还是一些通用的xslt? xml 文件是从客户端接收的一些数据,因此我无法控制它们将其发送给我的方式。

L.E.基本上,当我试图在 excel 中测试这些数据时(例如,我想确保 childOfChild7 的属性对应于正确的身份 ID)我得到了很多空格。如果我在访问中导入以仅获取我想要的数据,我必须执行数千个子查询才能将它们全部放在一个漂亮的表中。基本上我只想查看一个对象的所有数据(一个对象 - 一行),然后删除/隐藏我不需要的列。

【问题讨论】:

  • 为什么要重新格式化原来的xml?您的新格式看起来非常非规范化...
  • 除了示例输出之外,您能否使用文字描述所需的转换,以便我们在推断转换规则时减少工作(和错误)?

标签: c# xml xslt xpath xml-parsing


【解决方案1】:

这是一个纯 XSLT 1.0 解决方案

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="OBJECT//*[not(self::identity) and text()]">
  <xsl:copy>
   <xsl:apply-templates select="text()"/>
  </xsl:copy>
  <xsl:apply-templates select="@* | node()[not(self::text())]"/>
 </xsl:template>

 <xsl:template match="OBJECT//*[not(self::identity) and (not(text()))]">
  <xsl:copy/>
  <xsl:apply-templates select="@*"/>
  <xsl:apply-templates select="node()"/>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:element name="{name()}">
   <xsl:value-of select="."/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="identity">
  <xsl:apply-templates/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<ROOT>
    <OBJECT>
        <identity>
            <id>123</id>
        </identity>
        <child2 attr = "aa">32</child2>
        <child3>
            <childOfChild3 att1="aaa" att2="bbb" att3="CCC">LN</childOfChild3>
        </child3>
        <child4>
            <child5>
                <child6>3ddf</child6>
                <child7>
                    <childOfChild7 att31="RR">1231</childOfChild7>
                </child7>
            </child5>
        </child4>
    </OBJECT>
    <OBJECT>
        <identity>
            <id>124</id>
        </identity>
        <child2 attr = "bb">212</child2>
        <child3>
            <childOfChild3 att1="ee" att2="ccc" att3="EREA">OP</childOfChild3>
        </child3>
        <child4>
            <child5>
                <child6>213r</child6>
                <child7>
                    <childOfChild7 att31="EE">1233</childOfChild7>
                </child7>
            </child5>
        </child4>
    </OBJECT>
</ROOT>

产生了想要的正确结果:

<ROOT>
   <OBJECT>
      <id>123</id>
      <child2>32</child2>
      <attr>aa</attr>
      <child3/>
      <childOfChild3>LN</childOfChild3>
      <att1>aaa</att1>
      <att2>bbb</att2>
      <att3>CCC</att3>
      <child4/>
      <child5/>
      <child6>3ddf</child6>
      <child7/>
      <childOfChild7>1231</childOfChild7>
      <att31>RR</att31>
   </OBJECT>
   <OBJECT>
      <id>124</id>
      <child2>212</child2>
      <attr>bb</attr>
      <child3/>
      <childOfChild3>OP</childOfChild3>
      <att1>ee</att1>
      <att2>ccc</att2>
      <att3>EREA</att3>
      <child4/>
      <child5/>
      <child6>213r</child6>
      <child7/>
      <childOfChild7>1233</childOfChild7>
      <att31>EE</att31>
   </OBJECT>
</ROOT>

【讨论】:

    【解决方案2】:

    你可以把它弄平。您获取 OBJECTS 的所有后代并将它们转换为元素。您应该亲自尝试一下,而不仅仅是接受我的代码,但它确实有效,因此您可以根据自己的想法对其进行测试。

    XElement root1 = XElement.Load(file1);
    XElement root = new XElement("ROOT",
        root1.Elements()
            .Select(o => new XElement(o.Name, o
                .Descendants()
                .Select(x =>
                {
                    List<XElement> list = new List<XElement>();
                    list.Add(new XElement(x.Name, x.HasElements ? "" : x.Value));
                    if (x.HasAttributes)
                        list.AddRange(x.Attributes()
                            .Select(a => new XElement(a.Name, a.Value))
                            );
                    return list;
                })
                ))
                .ToArray());
    

    PS。您在结果集中忘记了&lt;identity&gt;&lt;/identity&gt;

    【讨论】:

      【解决方案3】:

      只需使用 XmlSerializer 将其反序列化为一个类,这里​​是一个msdn post on it,基本上您构建一个与您的 xml 结构匹配的类,然后让 XmlSerializer 类进行转换,您不需要创建自己的解析器

      【讨论】:

        【解决方案4】:

        我不熟悉 C#,但我希望这至少能让你入门。我必须做一些类似的事情,我会得到一个 XML 文件并将信息解析到数据库中。

        我使用了一个 Java 库 ~ StAX。它将允许您使用父子系统轻松读取 XML 文件并将信息解析为另一个 XML 文件。我希望这会有所帮助。

        【讨论】:

          猜你喜欢
          • 2013-06-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-18
          • 2016-05-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多