在使用XSL将XML转换为XML时需要帮助
好的,我正在编辑原始帖子。我想我通过替换原始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>
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() < 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>
不错的解决方案巴勃罗,只使用模板匹配和应用模板。 +1 – Peter 2013-02-26 11:17:46
'
嗯,我们不会知道直到OP在他的文章中澄清他正在尝试做什么。我假设他正在尝试做什么,并为此发布了解决方案。我不认为我们可以假设它是否或者不需要重命名(想象他将在此之后使用XML Schema来验证输出XML) – 2013-02-26 13:00:55
你的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>
您发布的输出与XSLT模板(输出中没有AKA_LIST元素)不匹配。 – 2013-02-26 11:04:32
' JOHN FILTER'用AKA打开关闭ALIAS,验证错误..确定您的输入XML。 –
2013-02-26 11:59:51
我不明白,你的代码中有'',但你的输出中有''和''?究竟你想要哪一个? –
2013-02-26 12:11:55