在xslt中解析xml格式的文本变量以使用“value-of”

时间:2016-04-19 12:33:03

标签: xml parsing xslt

我有一个以下结构的xml:

MeasurementDataExport Comments ApiCall username lotId processToolId

这是一个最小的例子:

<MeasurementDataExport xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://my.company.de/Measurement/MeasurementDataExport.xsd">
  <Name>MyTestName</Name>
  <Comments>&lt;ApiCall&gt;&lt;username&gt;AName&lt;/username&gt;&lt;lotId&gt;12345&lt;/lotId&gt;&lt;processToolId&gt;67890&lt;/processToolId&gt;&lt;/ApiCall&gt;</Comments>

我正在使用xlst来获取值username。以下是我获得评论价值的方法:

<xsl:variable name="comments">
  <xsl:copy-of select="mde:MeasurementDataExport/mde:Comments"/>
</xsl:variable>

这是变量输出的外观:

<ApiCall><username>Test</username><lotId>12345</lotId><processToolId>67890</processToolId></ApiCall>

如您所见,变量采用xml格式,且&amp; lt和&amp; gt字符已更改为&gt;和&lt;。但在调试时,他将该值存储为“text”类型。所以我不能深入挖掘

<xsl:value-of select="$comments/ApiCall/username" />

这是主要问题:我的架构只在节点注释之前有效,所有更深层次的东西都需要解析。那么如何将“注释”的值解析为节点结构,以便我可以使用更深入的调用值?

我尝试使用node-set,但到目前为止没有成功。

2 个答案:

答案 0 :(得分:1)

<xsl:variable>不包含节点集(在XSLT 1.0中)。它确实包含RTF(结果树片段)。 RTF有限制,你不能在它们上使用XPath表达式,因此你的行

<xsl:value-of select="$comments/ApiCall/username" />

最多只返回一个字符串,但不是一个完整的节点集。 解决方案是使用XSLT 2.0处理器。因为在XSLT 2.0中,此限制已被删除,see here in section "Death To the Result Tree Fragment!"

  

在XSLT 1.0中,结果树片段(RTF)类型就像一个节点集,但它实际上是一个二等公民。每当使用xsl:variable构造临时树时,都会获得RTF。问题是你不能再使用XPath表达式访问这棵树的内部,除非你使用特定于供应商的扩展函数,通常称为node-set(),将RTF转换为一流的node-set(由一个根节点组成)。 RTF数据类型的基本原理是它可以减少实现负担,但由于几乎所有现有的XSLT处理器都提供了自己版本的node-set()扩展函数,所以这种考虑已经没有实际意义了。

现在的方式,您必须从username标记下的text()节点中提取<Comments>,将;lt;视为文本,而不是<像michael.hor257k在另一条评论中写道。

<xsl:template match="/">
  <xsl:variable name="userName" select="substring-before(substring-after(mde:MeasurementDataExport/mde:Comments/text(),'&lt;username&gt;'),'&lt;/username&gt;')" />
  <xsl:value-of select="$userName"/>
</xsl:template>

答案 1 :(得分:1)

这里有几个问题 - 第一个问题是您的XML 具有您声明的结构。显示的片段的实际结构是:

MeasurementDataExport
• Name (contains a text node)
• Comments (contains a text node)

Comments的字符串值中的转义标记不是XML,无法使用XPath进行解析。这与变量无关 - 如果您尝试直接在原始节点上进行操作,则不会再有任何成功。

@ hr_117在评论中指出了第二个问题:如果您希望变量包含 node-set (在XSLT 1.0中),请使用select代替{ {1}}。但是,在这种情况下它不会产生影响,因为内容仍然不是XML。

为了从转义标记中提取值(例如用户名),您必须使用字符串函数 - 这不是非常强大 - 或者(最好)处理两个来源传递,第一遍将取消xsl:copy并将结果保存到临时文件。然后,您将能够将中间结果解析为XML。