将特定节点复制到新生成的xml

时间:2016-06-23 06:36:40

标签: xml xslt

我有以下xml:

<?xml version="1.0"?>
<class>

    <students>
        <student rollno="393">
            <firstname>
                <isDisplayInTOC>false</isDisplayInTOC>
                <lastname>Kad</lastname>                    
                <nickname>Dinkar</nickname>
                    <marks>85</marks>
            </firstname>
        </student>

        <student rollno="493">
            <firstname>
                <isDisplayInTOC>true</isDisplayInTOC>
                <lastname>Gupta
                    <nickname>Vinni</nickname>
                    <marks>95</marks></lastname>
            </firstname>
        </student>

        <student rollno="593">
            <firstname>
                <isDisplayInTOC>false</isDisplayInTOC>
                <lastname>Singh
                    <nickname>Jazz</nickname></lastname>
                    <marks>90</marks>
            </firstname>
        </student>
    </students>
</class>

我正在使用的xsl是:

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

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

  <xsl:template match="firstname">  
    <xsl:copy>
      <xsl:apply-templates select="@*|text|lastname"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="text">  
    <isDisplayInTOC>
      <xsl:value-of select="." />
    </isDisplayInTOC>
  </xsl:template>
</xsl:stylesheet>

我得到的输出是:

<?xml version="1.0" encoding="UTF-8"?>
<class>
    <students>
        <student rollno="393">
            <firstname>
                <lastname>Kad</lastname>
            </firstname>
        </student>
        <student rollno="493">
            <firstname>
                <lastname>
                    Gupta
                    <nickname>Vinni</nickname>
                    <marks>95</marks>
                </lastname>
            </firstname>
        </student>
        <student rollno="593">
            <firstname>
                <lastname>
                    Singh
                    <nickname>Jazz</nickname>
                </lastname>
            </firstname>
        </student>
    </students>
</class>

期望的输出:

<?xml version="1.0"?>
<class>
    <students>
    <student rollno="393">
        <firstname>
            <text>true</text>
            <lastname>Kad</lastname>
            <nickname>Dinkar</nickname>
            <marks>85</marks>
        </firstname>
    </student>

    <student rollno="493">
        <firstname>
            <text>true</text>
            <lastname>
                Gupta
                <nickname>Vinni</nickname>
                <marks>95</marks>
            </lastname>
        </firstname>
    </student>

    <student rollno="593">
        <firstname>
            <text>true</text>
            <lastname>
                Singh
                <nickname>Jazz</nickname>
            </lastname>
            <marks>90</marks>
        </firstname>
    </student>
</students>
<Employees>
    <student rollno="393">
        <firstname>
            <isDisplayInTOC>false</isDisplayInTOC>
            <lastname>Kad</lastname>
        </firstname>
    </student>

    <student rollno="493">
        <firstname>
            <isDisplayInTOC>true</isDisplayInTOC>
            <lastname>
                Gupta
                <nickname>Vinni</nickname>
                <marks>95</marks>
            </lastname>
        </firstname>
    </student>

    <student rollno="593">
        <firstname>
            <isDisplayInTOC>false</isDisplayInTOC>
            <lastname>
                Singh
                <nickname>Jazz</nickname>
            </lastname>
        </firstname>
    </student>
</Employees>
</class>

我想创建一个xslt文件,该文件将所有数据复制到新xml中的“lastname”节点,并将节点保留在此节点下面。 我能够遍历到姓氏但不能复制除了姓氏之外的名字节点.....我也能够复制姓氏节点,但不能复制它上面的任何节点 请帮助!

1 个答案:

答案 0 :(得分:1)

查看您的预期输出,我假设以下逻辑

  • 按原样复制所有student个节点,但firstName
  • 除外
  • firstname添加text元素,并复制isDiplayInTOC以外的所有其他内容
  • 还在现有Employees节点之后创建students节点,该节点包含student
  • 的副本
  • 对于Student下的Employees个节点,仅包含isDisplayInTOClastname

对于第一条规则,您使用XSLT identity template

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

转换firstname有一个单独的模板

<xsl:template match="firstname">
  <xsl:copy>
    <text>true</text>
    <xsl:copy-of select="node()[not(self::isDisplayInTOC)]" />
  </xsl:copy>
</xsl:template>

要复制Student下的Employees个节点,最好使用xsl:for-each来避免冲突模板,可能除了firstname

<Employees>
  <xsl:for-each select="student">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="firstname" mode="employee"/>
    </xsl:copy>            
  </xsl:for-each>
</Employees>

试试这个XSLT

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

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

  <xsl:template match="students">
    <xsl:copy>
      <xsl:apply-templates select="student"/>
    </xsl:copy>
    <Employees>
      <xsl:for-each select="student">
        <xsl:copy>
          <xsl:apply-templates select="@*"/>
          <xsl:apply-templates select="firstname" mode="employee"/>
        </xsl:copy>            
      </xsl:for-each>
    </Employees>
  </xsl:template>

  <xsl:template match="firstname">
    <xsl:copy>
      <text>true</text>
      <xsl:copy-of select="node()[not(self::isDisplayInTOC)]" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="firstname" mode="employee">
    <xsl:copy>
      <xsl:copy-of select="isDisplayInTOC|lastname" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>