XSLT:读取';s作为字符串传递的xml文档

XSLT:读取';s作为字符串传递的xml文档,xml,string,xslt,Xml,String,Xslt,我遇到了另一位工程师的问题。作为一名新工程师,我必须想出解决这个问题的办法,但我一直没能。任何帮助都将不胜感激,我找到的最接近的东西是,但仍然不在那里。我只能使用XSLV1.0 一个参数作为一个巨大的字符串传递给我的样式表。它最初来自一个XML文档。这根绳子看起来像这样 其中,$servers是传递给我的字符串的参数。字符串如下所示: MIKE1800SUSIE01014-07-04T00:00:00Z5238568Zoe500010 这是作为参数传递到样式表的xml数据的一部分。实际文档大约有

我遇到了另一位工程师的问题。作为一名新工程师,我必须想出解决这个问题的办法,但我一直没能。任何帮助都将不胜感激,我找到的最接近的东西是,但仍然不在那里。我只能使用XSLV1.0

一个参数作为一个巨大的字符串传递给我的样式表。它最初来自一个XML文档。这根绳子看起来像这样

其中,
$servers
是传递给我的字符串的参数。字符串如下所示:

MIKE1800SUSIE01014-07-04T00:00:00Z5238568Zoe500010

这是作为参数传递到样式表的xml数据的一部分。实际文档大约有300行数据。区分这些“节点”的唯一区别是
。如果这是一个非常大的字符串,有没有办法从中提取数据

比如说。我需要找到“佐伊”,看看她是否有“过期”,如果她没有,我需要她的“状态”。所以Zoe将显示“1”作为状态,因为她没有过期时间。MIKE将显示“0”,Susie将显示2014-07-04T00:00:00Z


为了找到解析/读取巨大字符串的解决方案,我在google和stack overflow上到处寻找。但我还没有找到一个解决方案,我可以让它发挥作用。到目前为止,我一直没有工作副本,研究了2天也没有取得任何进展。

字符串不是XML,不能解析为XML。当然,您可以使用XSLT1.0提供的字符串函数将字符串解析为字符串,这将非常繁琐且容易出错

如果可能,将路径作为参数传递给实际的XML文档。或者,依次调用两个转换,第一个转换将参数保存到具有已知路径的文件中,第二个转换从该文件中读取

另请参见:

正如@michael.hor257k在接受的答案中正确地观察到的那样,不可能将字符串解析为XML,但有一种方法可以将字符串作为节点集,将其作为嵌入文档加载。这可以与
document()一起使用。但是,警告这取决于实现(处理器不需要支持任何uri方案)。我用XSLT1.0处理器(如Xalan和Saxon 6)对此进行了测试,结果证明是可行的

解决方案是将字符串附加到数据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>


更新:此功能还取决于解析器对数据URI的支持。我没有意识到这一点,因为我的XML环境有这种支持,所以更改不同的XSLT处理器没有任何区别。我在MacOSX环境中使用了OxygenXMLEditor 15.2。当我准确地发现它使用的解析器时,我将更新此信息。

字符串不是XMl,不能解析为XMl。你不可能把实际XML文档的路径作为参数传递吗?4天前我给另一位工程师发了电子邮件,他在世界各地,但没有回音。所以我认为,这是他想要的方式。我想也许我错过了一些能读懂那样的字符串的东西。我知道我可以测试某个关键字的字符串,如MIKE或Zoe,但我不认为我可以测试关键字后的数据,对吗?可以使用XSLT 1.0提供的字符串函数将字符串解析为字符串,这将非常繁琐且容易出错。您应该努力将输入处理为XML—这意味着(1)访问XML文件中的原始数据;或者(2)连续进行两次转换,第一次转换将参数保存到具有已知路径的文件中,第二次转换从该文件中读取。您的第一个解决方案是将参数作为XML文档发送,原始数据就是我想到的解决方案。我会再和工程师谈谈,看看能否改变他的想法。谢谢你的帮助,让我确信我走上了正确的道路!你能在上面贴一个答案吗?我会把它标记为已回答和已结束。这是一个有趣的想法,但是我不能在任何处理器上复制你的成功。我同时使用Saxon和Xalan收到“格式错误的URL”警告。你能在这里纠正这个例子吗:@michael.hor257k它似乎也取决于解析器对数据uri的支持。它在Oxygen XML Editor 15.2(和命令行环境,共享相同的配置)中工作,但我还不能让它与标准Java 8 TraX实现一起工作。