XSLT将文本节点解析为XML?

XSLT将文本节点解析为XML?,xml,string,parsing,xslt,Xml,String,Parsing,Xslt,在我转换的XML文档中间,有一个CDATA节点,我知道它本身是由XML组成的。我希望将其“递归解析”为XML,这样我也可以对其进行转换。经过查找,我认为我的问题与您的问题非常相似 那是一年前的事了:我想澄清一下: 它说某些XSLT不能一次性完成这项工作:相反,您需要一种两阶段的方法。我刚刚买了一本关于XSLT2.0的新书。是否仍然没有XSLT指令将字符串节点“重新解析”为XML 在我的例子中,XML字符串节点只是整个节点中的一个节点。因此,在第1阶段,我将只转换输入XML文档的一个片段;其余部分

在我转换的XML文档中间,有一个CDATA节点,我知道它本身是由XML组成的。我希望将其“递归解析”为XML,这样我也可以对其进行转换。经过查找,我认为我的问题与您的问题非常相似

那是一年前的事了:我想澄清一下:

  • 它说某些XSLT不能一次性完成这项工作:相反,您需要一种两阶段的方法。我刚刚买了一本关于XSLT2.0的新书。是否仍然没有XSLT指令将字符串节点“重新解析”为XML
  • 在我的例子中,XML字符串节点只是整个节点中的一个节点。因此,在第1阶段,我将只转换输入XML文档的一个片段;其余部分需要通过第二阶段,保持不变。我看到了几种不变地将输入传递到输出的解决方案,但它们通常看起来“大部分都有效”,但跳过/不处理某些类型的节点输入。是否有一个可靠的结构,可以在不做任何更改的情况下将其余的输入传递到输出
  • 这种方法依赖于我能够分别应用两种变换。我(现有应用程序)只允许进行一次转换(XML输出是固定的;它由一个XSLT文件进行转换;我唯一能做的就是将我喜欢的任何东西放入该XSLT文件,和/或添加更多XSLT文件,但我不能影响通过一个XSLT文件传递XML的顶级调用)。我是否可以将任何东西放入XSLT文件中,从而调用第二个XSLT转换

  • 请参见末尾的更新。

  • 最重要的问题。这是可能的;问题是,您是否必须用XSLT手动编写XML解析器,或者使用扩展函数,或者是否有一个方便的、可移植的解决方案Update:如果您可以使用Saxon的()扩展函数,那是目前为止您最好的选择。你有权使用它吗

  • 答案很简单:是的,使用。这不会保留输入XML的所有词汇详细信息,例如属性的顺序,或者是否将
    编写为
    。然而,它将保留所有应该对XML处理器重要的细节

    但是如果不能在管道中运行两个样式表,这对您没有帮助,对吗

  • 嗯。。。不健全。如果您的输出将由浏览器显示,或者由其他理解的东西处理,您可以输出其中一个,并希望(与规范的建议相反!)序列化和解析将发生在这个样式表和您在输出时关联的样式表之间。但这将是非常脆弱的。我说“反对规范的建议”,因为它说

    当这个或任何其他机制 产生一个以上的序列 要应用的XSLT样式表 同时创建一个XML文档,然后 效果应该与 应用一个样式表 导入序列中的每个成员 命令

    这意味着,在这两者之间没有序列化和解析。不推荐

  • 更新:一条新评论说,您事先不知道哪些元素将包含CDATA节。我得出的结论是,这意味着您不知道哪些元素将包含未分析的数据(因为XML处理器本身并不知道或关心CDATA部分中的元素)。在这种情况下,所有赌注都输光了。您可能知道,XML处理器不应该知道XML输入文档的哪些部分位于CDATA部分
    CDATA
    只是一种不同的转义标记的方法,是
    等的替代方法。一旦数据被解析(不在XSLT处理器的管辖范围内),您就无法知道它最初是如何在标记中表示的。无论用
    还是
    表示,左尖括号都保持左尖括号。就像在C中一样,将字符指定为“a”或65或0x41并不重要;一旦程序被编译,您的代码将无法分辨出差异

    因此,如果您没有其他方法来确定需要解析输入文档中的哪些数据,那么上述方法都不会对您有所帮助:您不知道在哪里应用saxon:parse(),也不知道如何手动解析,也不知道如何通过以下XSLT转换禁用输出转义

    解决办法:

    • 例如,您可以通过
      test=“contains(,”)
      猜测哪些节点包含未分析的数据。(请注意,这将测试左尖括号,不管它是表示为字符实体、CDATA节的一部分还是其他任何方式。)有时会出现误报,例如,如果文本节点包含字符串“year<2001”。或者您可以尝试解析每个文本节点(效率非常低),对于那些成功解析格式良好的XML文档的节点,输出树而不是文本

    • 或者您可以使用非XML工具(如)预处理XML,因此可以“查看”CDATA标记。但是您已经说过,除了单个XSLT之外,您无法控制任何东西

    • 或者,理想情况下,您可以将消息发送回链,告知您正在使用的XML不可行:它们需要以某种方式进行标记,而不是使用CDATA标记,该标记包含未分析的数据。通常,这可以通过指定某些元素名称或使用属性标志来实现。显然,这将取决于谁提供XML

    另一次更新 好了,现在我明白了:所以您知道哪个元素包含未解析的数据(并且您知道它用CDATA标记),但您不知道其他哪些数据可能用CDATA标记

    其想法是改变[即解析拉尔斯]已知的 CDATA节点(“fred”)转换为XML节点 把剩下的都留下 文件的原始输入, 这样就可以通过管道输送 “世代”