Возможно ли в XSL сгладить иерархию XML? - PullRequest
3 голосов
/ 26 марта 2011

У меня есть следующая структура 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 #, но мне не нужно сохранять иерархию (что затрудняет мнеdeserialize).

Существует ли XSL, который может преобразовать это, чтобы развернуть элементы управления и, если возможно, добавить атрибут в любой дочерний элемент управления с помощью ParentId = ""?

Спасибо за любые советы!

Ответы [ 3 ]

2 голосов
/ 26 марта 2011

Учитывая XML, XmlSerializer может создать график объектов, которые содержат те же данные экземпляра.
Это известно как XML de-serialization

Вам нужно посмотреть здесь:

1 голос
/ 27 марта 2011

Следующая таблица стилей:

<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>
1 голос
/ 26 марта 2011

Этот шаблон должен помочь вам начать. Я запускал его против .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>
...