我有一个以下结构的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><ApiCall><username>AName</username><lotId>12345</lotId><processToolId>67890</processToolId></ApiCall></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,但到目前为止没有成功。
答案 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(),'<username>'),'</username>')" />
<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。