在XSL中是否可以展平XML层次结构?

时间:2011-03-26 18:29:10

标签: c# .net xml xslt xml-deserialization

我对XML文件有以下结构:

<INSTANCE>
  <Sections>
    <Section>
      <Forms>
        <Form>
          <Control id="GroupHeading1">
            <Property/>
            <Property/>
          </Control>
          <Control id="GroupHeading2">
           <Property/>
            <Control id="TextBox">
              <Property/>
              <Property/>
            </Control>
          </Control>
        </Form>
      </Forms>
    </Section>
  </Sections>
</INSTANCE>

我试图将其反序列化为C#对象,但我不需要保留层次结构(这使我很难反序列化)。

是否有XSL可以将其转换为取消嵌套控件,并且如果可能的话,使用ParentId =“”向任何子控件添加属性?

感谢您的指导!

3 个答案:

答案 0 :(得分:2)

鉴于XML,XmlSerializer可以生成包含相同实例数据的对象图 这称为XML de-serialization

你需要看一下:

答案 1 :(得分:1)

此模板可以帮助您入门。我在.NET 2.0上运行它。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" method="xml"/>

    <xsl:template match="*">
        <xsl:element name="{name()}">
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="*"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="Form">
        <Form>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates select="//Control"/>
        </Form>
    </xsl:template>

    <xsl:template match="Control">
        <Control>
            <xsl:if test="ancestor::Control/@id">
                <xsl:attribute name="ParentID"><xsl:value-of select="ancestor::Control/@id"/></xsl:attribute>
            </xsl:if>
            <xsl:copy-of select="*|@*"/>
        </Control>
    </xsl:template>

</xsl:stylesheet>

这是输出(为了便于阅读而缩进)。

<INSTANCE>
    <Sections>
        <Section>
            <Forms>
                <Form>
                    <Control id="GroupHeading1">
                        <Property />
                        <Property />
                    </Control>
                    <Control id="GroupHeading2">
                        <Property />
                        <Control id="TextBox">
                            <Property />
                            <Property />
                        </Control>
                    </Control>
                    <Control ParentID="GroupHeading2" id="TextBox">
                        <Property />
                        <Property />
                    </Control>
                </Form>
            </Forms>
        </Section>
    </Sections>
</INSTANCE>

答案 2 :(得分:1)

以下样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
    <!-- first-level control elements -->
    <xsl:template match="Control">
        <Control>
            <xsl:copy-of select="@*|*[not(self::Control)]" />
        </Control>
        <xsl:apply-templates select="Control" />
    </xsl:template>
    <!-- nested control elements -->
    <xsl:template match="Control/Control">
        <Control ParentId="{../@id}">
            <xsl:copy-of select="@*|*[not(self::Control)]" />
        </Control>
        <xsl:apply-templates select="Control" />
    </xsl:template>
</xsl:stylesheet>

应用于以下文档(与原始文档相同,只有一个额外的嵌套级别用于演示目的):

<INSTANCE>
    <Sections>
        <Section>
            <Forms>
                <Form>
                    <Control id="GroupHeading1">
                        <Property />
                        <Property />
                    </Control>
                    <Control id="GroupHeading2">
                        <Property />
                        <Control id="TextBox">
                            <Property />
                            <Property />
                            <Control id="Grandchild">
                                <Property />
                            </Control>
                        </Control>
                    </Control>
                </Form>
            </Forms>
        </Section>
    </Sections>
</INSTANCE>

生成一个没有嵌套<Control>元素的输出

<INSTANCE>
    <Sections>
        <Section>
            <Forms>
                <Form>
                    <Control id="GroupHeading1">
                        <Property />
                        <Property />
                    </Control>
                    <Control id="GroupHeading2">
                        <Property />
                    </Control>
                    <Control ParentId="GroupHeading2" id="TextBox">
                        <Property />
                        <Property />
                    </Control>
                    <Control ParentId="TextBox" id="Grandchild">
                        <Property />
                    </Control>
                </Form>
            </Forms>
        </Section>
    </Sections>
</INSTANCE>