Create elements dynamically in XSLT

血红的双手。 提交于 2019-12-13 03:12:47

问题


I want to create as many <Group> elements as they are in the Main xml dynamically using XSLT as <Group folder ="Group1"> in the new Xml. Also, the <Data> element added as the last child should be added only once inside.

Main Xml

<Root>
    <ClassA>
    <Groups>
    <Group1>
        <Group2>
            <Group3>
             ............
            </Group3>
        </Group2>
    </Group1>
    </Groups>
    <Data>
        <Name>George</Name>
        <Class>A</Class>
    </Data>
    </ClassA> 
</Root>

I need an Xml like this

<Data>
    <ClassA>
    <Group folder = "Group1">
        <Group folder = "Group2">
            <Group folder = "Group3">
             ............

            <Data>
                <Name>George</Name>
                <Class>A</Class>
            </Data>
            </Group>
        </Group>
    </Group>

    </ClassA> 
</Data>

回答1:


Actually, you need the following templates:

  1. Matching Root. Generate <Data> element and inside it apply templates to the whole own content.

  2. Matching ClassA. Copy the own element and inside if apply templates to the content of the child Groups element.

  3. Matching elements with name containing Group and then a digit. Create Group element with proper folder attribute. Apply templates to its content (if any). If this element does not contain any child element, copy Data element from ancestor ClassA.

  4. The identity template.

So the whole script can look like below:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="ClassA">
    <xsl:copy><xsl:apply-templates select="Groups/*"/></xsl:copy>
  </xsl:template>

  <xsl:template match="*[matches(name(), 'Group\d')]">
    <xsl:element name='Group'>
      <xsl:attribute name="folder" select="name()"/>
      <xsl:apply-templates select="@*|node()"/>
      <xsl:if test="count(*) = 0">
        <xsl:copy-of select="ancestor::ClassA/Data"/>
      </xsl:if>
    </xsl:element>
  </xsl:template>

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

For a working example see http://xsltransform.net/nb9MWtw




回答2:


 <xsl:output method="xml" indent="yes"/>
    <xsl:template match="Root">
        <xsl:element name="Data">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="ClassA">
        <xsl:element name="ClassA">
            <group floder="{Groups/Group1/name()}">
                <group floder="{Groups/Group1/Group2/name()}">
                    <group floder="{Groups/Group1/Group2/Group3/name()}">
                        <xsl:value-of select="Groups/Group1/Group2/Group3"/>
                        <xsl:copy-of select="Data"/>
            </group>
                </group>
            </group>
        </xsl:element>
    </xsl:template>

Try if is benifial for you.



来源:https://stackoverflow.com/questions/51522971/create-elements-dynamically-in-xslt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!