我是XSLT世界的新手,所以如果我不使用正确的条款,请原谅我。
我需要与外部系统进行集成,此系统返回一个包含在CDATA中的字符串,类似于:
<Response xmlns="http://tempuri.org/">
<Result>
<![CDATA[
<resultcode>0</resultcode>
<message>OK</message>
<data><unitlist version="1"><unit version="1" unitid="%" abbreviation="%" name="Porcentaje" />
<unit version="1" unitid="1/2 lb." abbreviation="1/2 lb." name="1/2 libra" /><unit version="1" unitid="1/2 pt." abbreviation="1/2 pt." name="medias pintas" /><unit version="1" unitid="1/2 pulg." abbreviation="1/2 pulg." name="1/2 pulg." /><unit version="1" unitid="1/2&quot; cdr." abbreviation="1/2&quot; cdr." name="1/2 pulgada cuadrada" /></unitlist></data>
]]>
</Result>
</Response>
我需要检索数据节点,并将每个单元解析成如下所示:
<units>
<unit>
<id>%</id>
<name>Porcentaje</name>
<abbreviation>%</abbreviation>
</unit>
<unit>
<id>1/2 lb.</id>
<name>1/2 libra</name>
<abbreviation>1/2 lb.</abbreviation>
</unit>
</units>
我一直在阅读有关两个阶段转换的信息,并尝试使用以下方法将数据包装到变量中:
<xsl:value-of select="substring-before(substring-after(., '<data>'), '</data>')" disable-output-escaping="yes" />
它适用于转义文本标记和获取节点,但我无法使用它来迭代for-each并创建我需要的XML。
我需要在一个XSLT中执行此操作。
高级谢谢你的帮助。
答案 0 :(得分:0)
这是我见过的最恐怖的XML。
将此XML解析为树后,您会发现有一个文本节点包含:
<resultcode>0</resultcode>
<message>OK</message>
<data><unitlist version="1"><unit version="1" unitid="%" abbreviation="%" name="Porcentaje" />
<unit version="1" unitid="1/2 lb." abbreviation="1/2 lb." name="1/2 libra" /><unit version="1" unitid="1/2 pt." abbreviation="1/2 pt." name="medias pintas" /><unit version="1" unitid="1/2 pulg." abbreviation="1/2 pulg." name="1/2 pulg." /><unit version="1" unitid="1/2&quot; cdr." abbreviation="1/2&quot; cdr." name="1/2 pulgada cuadrada" /></unitlist></data>
,它是sort-of-xml,除了它没有包含的包装元素。因此,您需要将此文本节点作为字符串提取,将其包装在虚拟元素中,然后使用XML解析器对其进行解析。
当你完成这项工作后,你将拥有一棵树,其中有一个文本节点(数据元素的子节点)包含内容:
<unitlist version="1"><unit version="1" unitid="%" abbreviation="%" name="Porcentaje" />
<unit version="1" unitid="1/2 lb." abbreviation="1/2 lb." name="1/2 libra" /><unit version="1" unitid="1/2 pt." abbreviation="1/2 pt." name="medias pintas" /><unit version="1" unitid="1/2 pulg." abbreviation="1/2 pulg." name="1/2 pulg." /><unit version="1" unitid="1/2" cdr." abbreviation="1/2" cdr." name="1/2 pulgada cuadrada" /></unitlist></data>
哪个是XML ...所以您可以通过XML解析器,之后您将能够使用通常的XML API来访问@unitid等属性的内容。
任何设计这个的人都有一种变态的幽默感。这是一种奇怪的心态,使用“半磅”作为一个重量单位。
答案 1 :(得分:0)
我需要检索数据节点,并将每个单元解析成一些东西 像这样:
您的数据提供程序不希望您解析给定的XML。他们遇到了很多麻烦,让你感到特别困难。如果你不能说服他们改变他们的格式,那么我建议你采取以下步骤:
第1步:将以下样式表应用于输入XML:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://tempuri.org/"
exclude-result-prefixes="ns">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/ns:Response">
<result>
<xsl:value-of select="ns:Result" disable-output-escaping="yes"/>
</result>
</xsl:template>
</xsl:stylesheet>
并将结果保存到文件。
第2步:将以下样式表应用于步骤1中生成的文件:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/result">
<xsl:value-of select="data" disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>
并将结果保存到文件。
第3步:将以下样式表应用于步骤2中生成的文件:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/unitlist">
<units>
<xsl:for-each select="unit">
<xsl:copy>
<id>
<xsl:value-of select="@unitid" />
</id>
<name>
<xsl:value-of select="@name" />
</name>
<abbreviation>
<xsl:value-of select="@abbreviation" />
</abbreviation>
</xsl:copy>
</xsl:for-each>
</units>
</xsl:template>
</xsl:stylesheet>
为清楚起见,这些是您应该在每个步骤中获得的结果:
第1步
<?xml version="1.0" encoding="UTF-8"?>
<result>
<resultcode>0</resultcode>
<message>OK</message>
<data><unitlist version="1"><unit version="1" unitid="%" abbreviation="%" name="Porcentaje" />
<unit version="1" unitid="1/2 lb." abbreviation="1/2 lb." name="1/2 libra" /><unit version="1" unitid="1/2 pt." abbreviation="1/2 pt." name="medias pintas" /><unit version="1" unitid="1/2 pulg." abbreviation="1/2 pulg." name="1/2 pulg." /><unit version="1" unitid="1/2&quot; cdr." abbreviation="1/2&quot; cdr." name="1/2 pulgada cuadrada" /></unitlist></data>
</result>
第2步
<?xml version="1.0" encoding="UTF-8"?>
<unitlist version="1"><unit version="1" unitid="%" abbreviation="%" name="Porcentaje" />
<unit version="1" unitid="1/2 lb." abbreviation="1/2 lb." name="1/2 libra" /><unit version="1" unitid="1/2 pt." abbreviation="1/2 pt." name="medias pintas" /><unit version="1" unitid="1/2 pulg." abbreviation="1/2 pulg." name="1/2 pulg." /><unit version="1" unitid="1/2" cdr." abbreviation="1/2" cdr." name="1/2 pulgada cuadrada" /></unitlist>
第3步
<?xml version="1.0" encoding="UTF-8"?>
<units>
<unit>
<id>%</id>
<name>Porcentaje</name>
<abbreviation>%</abbreviation>
</unit>
<unit>
<id>1/2 lb.</id>
<name>1/2 libra</name>
<abbreviation>1/2 lb.</abbreviation>
</unit>
<unit>
<id>1/2 pt.</id>
<name>medias pintas</name>
<abbreviation>1/2 pt.</abbreviation>
</unit>
<unit>
<id>1/2 pulg.</id>
<name>1/2 pulg.</name>
<abbreviation>1/2 pulg.</abbreviation>
</unit>
<unit>
<id>1/2" cdr.</id>
<name>1/2 pulgada cuadrada</name>
<abbreviation>1/2" cdr.</abbreviation>
</unit>
</units>
另一种方法是使用字符串函数提取数据,这将非常繁琐且容易出错。