2013-02-26 80 views
0

好的,我正在编辑原始帖子。我想我通过替换原始XML的名称标签尝试了一下。不管怎么说,这里是从原始文件的摘录:在使用XSL将XML转换为XML时需要帮助

<EMPLOYEE_LIST> 
    <EMPLOYEES> 
     <EMPLOYEE> 
     <EMPID>650000</EMPID> 
     <FIRST_NAME>KEITH</FIRST_NAME> 
     <MIDDLE_NAME>HUTCHINSON</MIDDLE_NAME> 
     <LAST_NAME>ROGERS</LAST_NAME> 
     <EMP_TYPE></EMP_TYPE> 
     <EMP_REF_ID>500000</EMP_REF_ID> 
     <JOINED_ON>2001-10-06</JOINED_ON> 
     <COMMENTS>Miscellanous Comments</COMMENTS> 
     <NATIONALITY> 
      <VALUE>American</VALUE> 
     </NATIONALITY> 
     <EMP_AKA> 
      <AKA_NAME>Danny</AKA_NAME> 
     </EMP_AKA> 
     <EMP_AKA> 
      <AKA_NAME>Dan</AKANAME> 
     </EMP_AKA> 
     <EMP_AKA> 
      <AKA_NAME>Ray</AKA_NAME> 
     </EMP_AKA> 
     <EMP_ADDR> 
      <STREET> </STREET> 
      <CITY> </CITY> 
      <STATE> </STATE> 
      <ZIP> </ZIP> 
      <COUNTRY> </COUNTRY> 
     </EMPLOYEE> 
    </EMPLOYEES> 
</EMPLOYEE_LIST> 

,我与上面的XML面临的问题是,我无法找到一个方法来适应多个AKA(又称)在一个单一的财产属性和我使用这种转变的XSL如下:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
     <xsl:template match="/EMPLOYEE_LIST"> 
      <employees> 
       <xsl:apply-templates select="EMPLOYEES/node()"/> 
      </employees>   
     </xsl:template> 

     <xsl:template match="EMPLOYEE"> 
     <employee> 
      <xsl:apply-templates select="*"/> 
     </employee> 
     </xsl:template> 

     xsl:template match="EMPLOYEE/EMPID"> 
     <emp_id> 
      <xsl:value-of select="."/> 
     </emp_id> 
     </xsl:template> 

      <xsl:template match="EMPLOYEE/FIRST_NAME"> 
     <f_name> 
      <xsl:value-of select="."/> 
     </f_name> 
     </xsl:template> 

     <xsl:template match="EMPLOYEE/MIDDLE_NAME"> 
      <m_name> 
       <xsl:value-of select="."/> 
      </m_name> 
     </xsl:template> 

     <xsl:template match="EMPLOYEE/LAST_NAME"> 
      <l_name> 
       <xsl:value-of select="."/> 
      </l_name> 
     </xsl:template> 
     . 
     . 
     . 
     . 
     . 
     <xsl:template match="EMPLOYEE/EMP_AKA"> 
     <aka_list> 
      <xsl:for-each select="AKA_NAME"> 
       <aka> 
        <xsl:for-each select="."> 
         <xsl:apply-templates/> 
        </xsl:for-each> 
       </aka> 
      </xsl:for-each> 
     </aka_list> 
    </xsl:template> 
</xsl:stylesheet> 

当应用到我的XML上述给出的XSL提供了以下的输出:

<?xml version="1.0" encoding="UTF-8"?> 
<employees> 
     <employee> 
     <emp_id>111345</emp_id> 
     <f_name>KEITH</f_name> 
     <m_name>HUTCHINSON</m_name> 
     <l_name>ROGERS</l_name> 
     <aka_list> 
      <aka>Danny</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Dan</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Ray</aka> 
     </aka_list> 
     </employee> 
</employees> 

而这并不是我牛逼rying实现,因为我需要在以下格式的数据:

<?xml version="1.0" encoding="UTF-8"?> 
<employees> 
     <employee> 
     <emp_id>111345</emp_id> 
     <f_name>KEITH</f_name> 
     <m_name>HUTCHINSON</m_name> 
     <l_name>ROGERS</l_name> 
     <aka_list> 
      <aka>Danny</aka> 
      <aka>Dan</aka> 
      <aka>Ray</aka> 
     </aka_list> 
     </employee> 
</employees 

有什么办法来实现这一目标?展望未来,XML中的元素数量巨大,例如AKA_NAME。

  <aka_list> 
      <aka>Danny</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Dan</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Ray</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Danny_2</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Dan_2</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Ray_2</aka> 
     </aka_list> 

改造应该只发扬顶部5和第六个应该被截断等:

  <aka_list> 
      <aka>Danny</aka> 
      <aka>Dan</aka> 
      <aka>Ray</aka> 
      <aka>Danny_2</aka> 
      <aka>Dan_2</aka> 
     </aka_list> 
+0

您发布的输出与XSLT模板(输出中没有AKA_LIST元素)不匹配。 – 2013-02-26 11:04:32

+0

' JOHN FILTER'用AKA打开关闭ALIAS,验证错误..确定您的输入XML。 – 2013-02-26 11:59:51

+0

我不明白,你的代码中有'',但你的输出中有''和''?究竟你想要哪一个? – 2013-02-26 12:11:55

回答

2

UPDATE:用于完整的XML解决方案。

我试图用XSLT模板中的注释来解释解决方案。

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

    <!-- Ignore text nodes by default --> 
    <xsl:template match="text()" /> 

    <!-- Transform tag name EMPLOYEES to employees --> 
    <xsl:template match="EMPLOYEES"> 
     <employees> 
      <xsl:apply-templates select="*" /> 
     </employees> 
    </xsl:template> 

    <!-- Transform tag name EMPLOYEE to employee --> 
    <xsl:template match="EMPLOYEE"> 
     <employee> 
      <xsl:apply-templates select="*" /> 
     </employee> 
    </xsl:template> 

    <!-- Transform tag name EMPID to emp_id --> 
    <xsl:template match="EMPID"> 
     <emp_id> 
      <xsl:value-of select="." /> 
     </emp_id> 
    </xsl:template> 

    <!-- Transform tag name FIRST_NAME to f_name --> 
    <xsl:template match="FIRST_NAME"> 
     <f_name> 
      <xsl:value-of select="." /> 
     </f_name> 
    </xsl:template> 

    <!-- Transform tag name MIDDLE_NAME to m_name --> 
    <xsl:template match="MIDDLE_NAME"> 
     <m_name> 
      <xsl:value-of select="." /> 
     </m_name> 
    </xsl:template> 

    <!-- Transform tag name LAST_NAME to l_name --> 
    <xsl:template match="LAST_NAME"> 
     <l_name> 
      <xsl:value-of select="." /> 
     </l_name> 
    </xsl:template> 

    <!-- When encounter the first EMP_AKA element, print itself and its following 
     siblings with the same name within an aka_list element --> 
    <xsl:template match="EMP_AKA[1]"> 
     <aka_list> 
      <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA/AKA_NAME" mode="print"/> 
     </aka_list> 
    </xsl:template> 

    <!-- Transform tag name EMP_AKA to aka --> 
    <xsl:template match="AKA_NAME" mode="print"> 
     <aka> 
      <xsl:value-of select="." /> 
     </aka> 
    </xsl:template> 

</xsl:stylesheet> 

更新2:如果你不想使用模板模式,因为AKA_NAME将被其他地方匹配,并以同样的方式处理,你可以通过这些的替换最后两个模板:

<!-- When encounter the first EMP_AKA element, print itself and its following 
    siblings with the same name within an aka_list element --> 
<xsl:template match="EMP_AKA[1]"> 
    <aka_list> 
     <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA/AKA_NAME" /> 
    </aka_list> 
</xsl:template> 

<!-- Exclude all EMP_AKA elements (except the first one because 
    the previous template has higher precedence than this one) --> 
<xsl:template match="EMP_AKA" /> 

<!-- Transform tag name EMP_AKA to aka --> 
<xsl:template match="AKA_NAME"> 
    <aka> 
     <xsl:value-of select="." /> 
    </aka> 
</xsl:template> 

<xsl:template match="EMP_AKA" /> 

此代码产生与上一个相同的输出。


UPDATE 3:OP询问如何限制输出AKA_NAME元件的数量。这是基于更新2的解决方案只是

<xsl:template match="EMP_AKA[1]"> 
    <aka_list> 
     <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA[position() &lt; 5]/AKA_NAME" /> 
    </aka_list> 
</xsl:template> 

<!-- Transform tag name EMP_AKA to aka --> 
<xsl:template match="AKA_NAME"> 
    <aka> 
     <xsl:value-of select="." /> 
    </aka> 
</xsl:template> 

<xsl:template match="EMP_AKA" /> 

原来的答案

的OP编辑的职位,并彻底改变了XML文件替换最后一个模板从更新2。以下是我以前的回答(似乎并没有删除它)。

如果你试图把所有的< AKA>元素为< AKA_LIST>元素(这是不明确的,因为你发布的不匹配转换的输出),那么你可以使用下面的转换:

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

    <!-- Just for demo --> 
    <xsl:template match="text()" /> 

    <!-- Match PERSON: create the list --> 
    <xsl:template match="PERSON"> 
     <AKA_LIST> 
      <xsl:apply-templates select="NAME/AKA" /> 
     </AKA_LIST> 
    </xsl:template> 

    <!-- Outputs the AKA element, changing the tag name --> 
    <xsl:template match="AKA"> 
     <aka> 
      <xsl:value-of select="." /> 
     </aka> 
    </xsl:template> 

</xsl:stylesheet> 

哪些改变你的源XML到:

<AKA_LIST> 
    <aka>ROSE PETAL</aka> 
    <aka>JOHN FILTER</aka> 
</AKA_LIST> 
+0

不错的解决方案巴勃罗,只使用模板匹配和应用模板。 +1 – Peter 2013-02-26 11:17:46

+0

''不需要..因为这不是重新命名的要求。另外一个更好的做法是覆盖身份模板.. – 2013-02-26 12:25:47

+0

嗯,我们不会知道直到OP在他的文章中澄清他正在尝试做什么。我假设他正在尝试做什么,并为此发布了解决方案。我不认为我们可以假设它是否或者不需要重命名(想象他将在此之后使用XML Schema来验证输出XML) – 2013-02-26 13:00:55

1

你的XSLT代码实际上混淆了,因为你有一个像<AKA_LIST>一些标签。所以,我会通过输入和输出的XML示例:这里是XSLT代码

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

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

    <xsl:template match="PERSON"> 
    <xsl:copy> 
     <xsl:apply-templates select="NAME[1]"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="NAME"> 
    <xsl:copy> 
     <xsl:apply-templates select="/PEOPLE/PERSON/NAME/AKA"/> 
    </xsl:copy> 
    </xsl:template> 


</xsl:stylesheet> 

输入XML:

<?xml version="1.0" encoding="utf-8"?> 
<PEOPLE> 
    <PERSON> 
    <NAME> 
     <REFERENCE>GOOD</REFERENCE> 
     <AKA>ROSE PETAL</AKA> 
     </NAME> 
    <NAME> 
     <REFERENCE>GOOD</REFERENCE> 
     <AKA>JOHN FILTER</AKA> 
     </NAME> 
    </PERSON> 
</PEOPLE> 

输出:

<?xml version="1.0" encoding="utf-8"?> 
<PEOPLE> 
    <PERSON> 
    <NAME> 
     <AKA>ROSE PETAL</AKA> 
     <AKA>JOHN FILTER</AKA> 
    </NAME> 
    </PERSON> 
</PEOPLE> 

说明:

<xsl:template match="@*|node()"> ...... 

从输入上面的代码拷贝标记输出AS IS *,其他模板匹配重写这个..

<xsl:template match="PERSON"> ...... 

上面的代码拷贝只有一个<NAME> TAG(第一)到输出..

<xsl:template match="NAME"> 
    <xsl:copy> 
     <xsl:apply-templates select="/PEOPLE/PERSON/NAME/AKA"/> 
     ...... 

上面的代码副本<NAME>下的所有<AKA>标签。由于我们仅复制一个<NAME>标记,所有<AKA>标记出现在<NAME>