我遇到了另一位工程师的问题。作为一名新工程师,我必须找到解决方案,但我还没能做到。任何帮助将不胜感激,我发现的最接近的事情是Chunk string with XSLT,但仍然不是那里。我只能使用XSL v1.0。
参数作为巨型字符串传递给我的样式表。它最初来自XML文档。字符串看起来像这样。
使用<xsl:value-of select="$servers"/>
,其中$servers
是传递给我的字符串的参数。字符串如下所示:
<license><active_servers><server><name>MIKE</name><capacity>18</capacity><status>0</status><expiration></expiration><left>0</left><comment></comment></server><server><name>Susie</name><capacity>0</capacity><status>1</status><expiration>2014-07-04T00:00:00Z</expiration><left>5238568</left><comment></comment></server><server><name>Zoe</name><capacity>5000</capacity><status>1</status><expiration></expiration><left>0</left><comment></comment></server></active_servers></license>
这是作为样式表的参数传递的xml数据的一部分。实际文档是300行左右的数据。区分这些&#34;节点的唯一区别是&#34;是<server>
和</server>
。如果它是一个非常大的字符串,有没有办法从中提取数据?
比如说。我需要找到&#34; Zoe&#34;并且看看她是否有过期&#34;如果她没有,我需要她&#34;状态&#34;。所以Zoe将展示&#34; 1&#34;状态,因为她没有到期。而MIKE将显示&#34; 0&#34;和Susie将展出2014-07-04T00:00:00Z。
我已经遍布google和堆栈溢出来寻找解析/读取巨型字符串的解决方案。但我还没有达到足够接近的解决方案,我可以让它发挥作用。截至目前,我没有工作副本,也没有任何地方进行研究2天。
答案 0 :(得分:3)
无法将字符串解析为XML,正如@ michael.hor257k在接受的答案中正确观察到的那样,但 是一种将字符串视为节点集的方法通过将其加载为嵌入式文档。使用带有document()
函数的data URI scheme即可。但是,XSLT 1.0 Specification警告说这是依赖于实现的(处理器不需要支持任何uri方案)。我使用Xalan和Saxon 6等XSLT 1.0处理器对它进行了测试,结果很有效。
解决方案是将您的字符串附加到以逗号分隔的数据URI方案data:text/xml
。然后,您可以将此字符串传递给document()
函数,它将其解析为XML文件:
document(concat('data:text/xml,',$servers))
然后,您可以将任何模板应用于节点集。
这是一个带有$servers
参数的样式表,它应该接收包含XML数据的字符串。它将解析字符串,转换模板中的节点,并使用一些数据生成XML输出:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:param name="servers"/>
<xsl:template match="/">
<xsl:apply-templates select="document(concat('data:text/xml,',$servers))/license"/>
</xsl:template>
<xsl:template match="license">
<results>
<xsl:apply-templates/>
</results>
</xsl:template>
<!-- server without expiration - get status -->
<xsl:template match="server[not(string(expiration))]">
<server name="{name}" status="{status}" />
</xsl:template>
<!-- server with expiration - get expiration -->
<xsl:template match="server">
<server name="{name}" expiration="{expiration}" />
</xsl:template>
</xsl:stylesheet>
如果你使用任何来源运行它,并且你的数据作为参数传递,你得到:
<results>
<server name="MIKE" status="0"/>
<server name="Susie" expiration="2014-07-04T00:00:00Z"/>
<server name="Zoe" status="1"/>
</results>
更新:此功能还取决于解析器对data-uris的支持。我没有意识到这一点,因为我的XML环境有这种支持,因此改变不同的XSLT处理器并没有任何区别。我在Mac OS X环境中使用了Oxygen XML Editor 15.2。当我发现它正在使用哪个解析器时,我将更新此信息。
答案 1 :(得分:2)
字符串不是XML,无法将解析为XML 。您当然可以使用XSLT 1.0提供的字符串函数将字符串解析为字符串 - 这将非常繁琐且容易出错。
如果可能,将路径作为参数传递给实际的XML文档。或者,串行调用两个转换,第一个转换将参数保存到具有已知路径的文件,并从该文件读取第二个转换。