我正在尝试使用XSLT进行转换。这是我的XML源:
<Memoria>
<seccion>
<contenido><p>TEXT</p>
<ul>
<li>LIST</li>
</ul>
<p>ANOTHER TEXT</p>
<p>&nbsp;</p></contenido>
</seccion>
</Memoria>
我正在尝试使用XSLT:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Memoria">
<cosa>
<xsl:for-each select="seccion">
<Address>
<xsl:for-each select="contenido">
<FirstName><xsl:value-of select="p" /></FirstName>
</xsl:for-each>
<ul>
<LastName><xsl:value-of select="ul/li" /></LastName>
</ul>
</Address>
</xsl:for-each>
</cosa>
</xsl:template>
</xsl:stylesheet>
得到这个:
<?xml version="1.0"?>
<cosa>
<Address>
<FirstName>TEXT</FirstName>
<ul>
<LastName>LIST</LastName>
</ul>
</Address>
</cosa>
但我希望:
<?xml version="1.0"?>
<cosa>
<Address>
<FirstName>TEXT</FirstName>
<ul>
<LastName>LISTr</LastName>
</ul>
<FirstName>ANOTHER TEXT</FirstName>
</Address>
</cosa>
我从外部应用程序获取此XML。
答案 0 :(得分:3)
罕见的转型?提供了适当的输入XML和所需的输出,它在XSLT中并不罕见..
老实说,我对您的示例输入和输出XML不满意。我想出了一个XML希望这就是你的XML真正的样子。如果没有,那么就提出精确的i / p和o / p XML。
<?xml version="1.0" encoding="utf-8"?>
<Memoria>
<seccion>
<contenido>
<p>TEXT</p>
<ul>
<li>Item1</li>
<li>Item2</li>
<li>Item3</li>
</ul>
<p>ANOTHER TEXT</p>
<ul>
<li>Itema</li>
<li>Itemb</li>
<li>Itemc</li>
</ul>
</contenido>
</seccion>
</Memoria>
对应的XSLT代码:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<cosa>
<xsl:apply-templates select="//contenido"/>
</cosa>
</xsl:template>
<xsl:template match="text()"/>
<xsl:template match="contenido">
<Address>
<xsl:apply-templates select="p|ul"/>
</Address>
</xsl:template>
<xsl:template match="p[not(contains(.,'&'))]">
<FirstName>
<xsl:value-of select="."/>
</FirstName>
</xsl:template>
<xsl:template match="ul">
<ul>
<xsl:for-each select="li">
<LastName>
<xsl:value-of select="."/>
</LastName>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
我不确定你想要实现什么......但是,以下XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Memoria">
<cosa>
<xsl:for-each select="seccion">
<Address>
<xsl:apply-templates select="contenido" />
</Address>
</xsl:for-each>
</cosa>
</xsl:template>
<xsl:template match="contenido">
<xsl:apply-templates select="p | ul" />
</xsl:template>
<xsl:template match="p">
<FirstName>
<xsl:value-of select="text()"/>
</FirstName>
</xsl:template>
<xsl:template match="ul">
<ul>
<LastName>
<xsl:value-of select="li"/>
</LastName>
</ul>
</xsl:template>
</xsl:stylesheet>
将产生以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<cosa>
<Address>
<FirstName>TEXT</FirstName>
<ul>
<LastName>LIST</LastName>
</ul>
<FirstName>ANOTHER TEXT</FirstName>
<FirstName>&nbsp;</FirstName>
</Address>
</cosa>
您现在可以考虑添加条件以从输出中排除&
元素:
<xsl:template match="p">
<xsl:if test="not(contains(text(), '&'))">
<FirstName>
<xsl:value-of select="text()"/>
</FirstName>
</xsl:if>
</xsl:template>
答案 2 :(得分:0)
xsl:value-of
将获取节点集中第一个元素的内容。如果您想对集合中的所有元素进行操作,则需要xsl:for-each
或xsl:apply-templates
。但是,如果你这样做,你会得到:
<?xml version="1.0"?>
<cosa>
<Address>
<FirstName>TEXT</FirstName>
<ul>
<LastName>LISTr</LastName>
</ul>
<FirstName>ANOTHER TEXT</FirstName>
<FirstName>& </FirstName>
</Address>
</cosa>
答案 3 :(得分:0)
假设您确定在第一个P元素中始终具有FirstName,并且在第二个P元素中具有第二个第一个名称,则可以使用公共node-set()函数来获取for-中的特定元素。每个循环:
以下修改后的XSLT会生成您在问题中所需的输出:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Memoria">
<cosa>
<xsl:for-each select="seccion">
<Address>
<xsl:for-each select="contenido">
<FirstName>
<xsl:value-of select="p" />
</FirstName>
<ul>
<LastName>
<xsl:value-of select="ul/li" />
</LastName>
</ul>
<FirstName>
<xsl:value-of select="exsl:node-set(.)/p[2]/."/>
</FirstName>
</xsl:for-each>
</Address>
</xsl:for-each>
</cosa>
</xsl:template>
</xsl:stylesheet>
注意:我通常使用xmlns:msxsl =“urn:schemas-microsoft-com:xslt”作为node-set()函数,但我认为exsl不是特定于供应商的:)
如果您的XML结构不一致或不可预测,这可能会中断;否则它将工作,你不需要另一个for-each来获得第二个FirstName结果元素的第二个P元素。
我希望这有用!