2016-10-28 105 views
0

我是XSLT新手,目前正在使用xslt将输入XML上的递归函数转换为目标XML。使用XSLT递归

  1. 输入XML:
<?xml version="1.0" encoding="UTF-8"?> 
<referenced> 
<name>XYZ</name> 
<LOCK_STATUS>2</LOCK_STATUS> 
    <reference> 
     <name>MC</name> 
     <LOCK_STATUS>2</LOCK_STATUS> 
    </reference> 
    <reference> 
     <name>MC1</name> 
     <LOCK_STATUS>2</LOCK_STATUS> 
    </reference> 
    <reference> 
     <name>List</name> 
     <LOCK_STATUS>2</LOCK_STATUS> 
      <reference> 
       <name>entList</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
      <reference> 
       <name>ist</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
      <reference> 
       <name>WumentList</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
        <reference> 
         <name>WumentList</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </reference> 
        <reference> 
         <name>WumentList</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </reference> 
      </reference> 
    </reference> 
     <reference> 
     <name>entList</name> 
     <LOCK_STATUS>2</LOCK_STATUS> 
      <reference> 
       <name>entList</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
      <reference> 
       <name>ist</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
      <reference> 
       <name>WumentList</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
    </reference> 
</referenced> 
  • 目标XML我想要实现:
  • <?xml version="1.0" encoding="UTF-8"?> 
    <children> 
    <name>XYZ</name> 
    <LOCK_STATUS>2</LOCK_STATUS> 
        <children> 
         <name>MC</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </children> 
        <children> 
         <name>MC1</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </children> 
        <children> 
         <name>DocumentList</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
          <children> 
           <name>entList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>ist</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>WumentList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
            <children> 
             <name>WumentList</name> 
             <LOCK_STATUS>2</LOCK_STATUS> 
            </children> 
            <children> 
             <name>WumentList</name> 
             <LOCK_STATUS>2</LOCK_STATUS> 
            </children> 
          </children> 
        </children> 
        <children> 
         <name>st</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
          <children> 
           <name>entList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>ist</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>WumentList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
        </children> 
    </children> 
    
  • XSLT我写的函数:
  • <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8"/> 
         <xsl:template match="/"> 
         <xsl:apply-templates select="reference"/> 
         </xsl:template> 
         <xsl:template match="reference[reference]"> 
         <xsl:apply-templates select="reference"/> 
         </xsl:template> 
         <xsl:template match="reference"> 
         <children> 
          <name> 
          <xsl:value-of select="name" /> 
          </name> 
          <LOCK_STATUS> 
          <xsl:value-of select="LOCK_STATUS" /> 
          </LOCK_STATUS> 
         </children> 
        </xsl:template> 
    </xsl:stylesheet> 
    

    不知何故,我无法用我写的xslt实现目标XML。

    Hi Tim,

    感谢您对此的帮助。试图了解你提供的代码spinet和教程我去互联网了解更多:)

    不在我的情况下,我不必重命名引用引用。

    将如何XSLT变化,如果预期输出XML应该出现这样的你是你的根元素被命名为referenced,但在你的第一个模板是寻找一个根元素

    <?xml version="1.0" encoding="UTF-8"?> 
    <nodeInfo> 
    <name>XYZ</name> 
    <LOCK_STATUS>2</LOCK_STATUS> 
        <children> 
         <name>MC</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </children> 
        <children> 
         <name>MC1</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </children> 
        <children> 
         <name>DocumentList</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
          <children> 
           <name>entList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>ist</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>WumentList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
            <children> 
             <name>WumentList</name> 
             <LOCK_STATUS>2</LOCK_STATUS> 
            </children> 
            <children> 
             <name>WumentList</name> 
             <LOCK_STATUS>2</LOCK_STATUS> 
            </children> 
          </children> 
        </children> 
        <children> 
         <name>st</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
          <children> 
           <name>entList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>ist</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>WumentList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
        </children> 
    </nodeInfo> 
    
    +0

    我已经修改了我的答案,但是如果您没有为您的问题添加第二个输入XML,而是将原始输入XML修改为您想要的内容,将会很清楚。谢谢! –

    回答

    1

    的一个问题的reference

    <xsl:template match="/"> 
         <xsl:apply-templates select="reference"/> 
        </xsl:template> 
    

    /符号的顶级文档节点,这是您的XML(你的情况referenced)的单根元素的父匹配。

    您也不需要第二个匹配reference[reference]的模板,因为这会跳过任何reference元素与子元素reference,这不是您想要的。

    但是如果你想递归,你只需要一个xsl:apply-templates添加到您的模板匹配reference

    试试这个XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8"/> 
    
        <xsl:template match="referenced"> 
         <nodeInfo> 
          <name> 
          <xsl:value-of select="name" /> 
          </name> 
          <LOCK_STATUS> 
          <xsl:value-of select="LOCK_STATUS" /> 
          </LOCK_STATUS> 
          <xsl:apply-templates select="reference" /> 
         </nodeInfo> 
        </xsl:template> 
    
        <xsl:template match="reference"> 
         <children> 
          <name> 
          <xsl:value-of select="name" /> 
          </name> 
          <LOCK_STATUS> 
          <xsl:value-of select="LOCK_STATUS" /> 
          </LOCK_STATUS> 
          <xsl:apply-templates select="reference" /> 
         </children> 
        </xsl:template> 
    </xsl:stylesheet> 
    

    更妙的是,利用identity template,这对减少了你需要做的工作(因为看起来你所要做的只是将referenced重命名为nodeInfo,referencechildren):

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8"/> 
    
        <xsl:template match="@*|node()"> 
         <xsl:copy> 
          <xsl:apply-templates select="@*|node()"/> 
         </xsl:copy> 
        </xsl:template> 
    
        <xsl:template match="referenced"> 
         <nodeInfo> 
          <xsl:apply-templates /> 
         </nodeInfo> 
        </xsl:template> 
    
        <xsl:template match="reference"> 
         <children> 
          <xsl:apply-templates /> 
         </children> 
        </xsl:template> 
    </xsl:stylesheet> 
    
    +0

    身份模板是否有助于复制引用到nodeInfo中的所有内容,并引用了子节点,只要它们的结构相同? – Nis

    +0

    是的。身份模板用于复制您不想更改的所有节点和属性。在这种情况下,您正在使用'children'替换'reference',但保留所有后代节点,因此身份模板将为您处理这些内容。 –

    +0

    但在我的结尾它没有发生。输入xml已被修改了一点,现在引用有一些额外的派生节点。在xslt被应用之后(标识模板),在输出xml中也没有看到。我可以重新发布输入xml吗? – Nis