XSL 动态 XPath 评估
XSL Dynamic XPath evaluation
<name>
<pattern>/Book/Title</pattern>
<pattern>/Newspaper/Title</pattern>
</name>
<Description>
<pattern>/Book/Descriptions/*</pattern>
<pattern>/Newspaper/Descriptions/*<pattern>
</Description>
我有一组不同的 XML 文件。给定一个如上所述的 XML 文件,我想从所有这些文件中提取语义相似的信息并以 JSON 格式显示。例如。我可能想从 XMLs 编码书籍信息之一中提取名称和描述以接收如下文件:
"name": "Harry Potter",
"description": ["DescA", "DescB"]
属于那个的 XML 文件可能看起来像:
<Book>
<Title>Harry Potter</Title>
<Author>J.K. Rowling </Author>
<Description lang="de">DescA</Description>
<Description lang="en">DescB</Description>
</Book>
我考虑过使用 XSL 3.0 来使用 xsl:evaluate
函数,但它并没有像我预期的那样工作。
使用如下代码片段:
<xsl:variable name="pattern">
<xsl:evaluate xpath="/Book/Descriptions/*" context-item="$root"/>
</xsl:variable>
<xsl:for-each select="$pattern">
<xsl:value-of select="."/>
<xsl:text>,</xsl:text>
</xsl:for-each>
我只能将所有描述作为一个长的串联字符串获取,而无法循环遍历它们。我本来希望得到像“DescA,DescB”这样的输出,但只得到“DescADescB”。
我对 XSL 非常陌生,因此不胜感激。无论是如何以更有效的方式设计上述映射,还是如何以这种方式使用评估函数,我都可以获得单独的描述。
有关信息,当前使用 Saxon XSL HE 10.5 和 Java.
从简单的例子开始
<xsl:template match="/">
<xsl:value-of separator=",">
<xsl:evaluate xpath="'Book/Description'" context-item="."/>
</xsl:value-of>
</xsl:template>
对于您的示例,
<Book>
<Title>Harry Potter</Title>
<Author>J.K. Rowling </Author>
<Description lang="de">DescA</Description>
<Description lang="en">DescB</Description>
</Book>
应该给DescA,DescB
.
存储在 xsl:variable
元素内构建的项目序列,例如xsl:evaluate
作为项目序列而不是结果树的子节点是通过使用例如实现的。 xsl:variable as="item()*" ...
,而不是通过更改您的 xsl:evaluate
。
我有点困惑,因为这里有两个 XML 文档,它们都包含匹配 Description
的元素,但都没有匹配 Book/Descriptions/*
的元素,包含要计算的模式(表达式)的那个不包含 Book 元素。
也许您真正的错误被 copy/paste 错误掩盖了。您选择的变量名称 pattern
也暗示您可能会感到困惑:xsl:evaluate
的结果不是模式(甚至不是 XPath 表达式),它是一组节点。
一个明确的错误是您没有在变量上指定 as
属性(这意味着 xsl:evaluate 的结果被复制到新的文档树中)。我希望是这样的:
<xsl:variable name="selected-nodes" as="node()*">
<xsl:evaluate xpath="//Description/pattern" context-item="$root"/>
</xsl:variable>
但我不确定这是否正是您想要的,因为 //Description/pattern
选择了多个表达式,而 xsl:evaluate
只会计算一个。如果你想评估多个模式并合并结果,那是可以的,但我需要更清楚地了解需求。
<name>
<pattern>/Book/Title</pattern>
<pattern>/Newspaper/Title</pattern>
</name>
<Description>
<pattern>/Book/Descriptions/*</pattern>
<pattern>/Newspaper/Descriptions/*<pattern>
</Description>
我有一组不同的 XML 文件。给定一个如上所述的 XML 文件,我想从所有这些文件中提取语义相似的信息并以 JSON 格式显示。例如。我可能想从 XMLs 编码书籍信息之一中提取名称和描述以接收如下文件:
"name": "Harry Potter",
"description": ["DescA", "DescB"]
属于那个的 XML 文件可能看起来像:
<Book>
<Title>Harry Potter</Title>
<Author>J.K. Rowling </Author>
<Description lang="de">DescA</Description>
<Description lang="en">DescB</Description>
</Book>
我考虑过使用 XSL 3.0 来使用 xsl:evaluate
函数,但它并没有像我预期的那样工作。
使用如下代码片段:
<xsl:variable name="pattern">
<xsl:evaluate xpath="/Book/Descriptions/*" context-item="$root"/>
</xsl:variable>
<xsl:for-each select="$pattern">
<xsl:value-of select="."/>
<xsl:text>,</xsl:text>
</xsl:for-each>
我只能将所有描述作为一个长的串联字符串获取,而无法循环遍历它们。我本来希望得到像“DescA,DescB”这样的输出,但只得到“DescADescB”。 我对 XSL 非常陌生,因此不胜感激。无论是如何以更有效的方式设计上述映射,还是如何以这种方式使用评估函数,我都可以获得单独的描述。 有关信息,当前使用 Saxon XSL HE 10.5 和 Java.
从简单的例子开始
<xsl:template match="/">
<xsl:value-of separator=",">
<xsl:evaluate xpath="'Book/Description'" context-item="."/>
</xsl:value-of>
</xsl:template>
对于您的示例,
<Book>
<Title>Harry Potter</Title>
<Author>J.K. Rowling </Author>
<Description lang="de">DescA</Description>
<Description lang="en">DescB</Description>
</Book>
应该给DescA,DescB
.
存储在 xsl:variable
元素内构建的项目序列,例如xsl:evaluate
作为项目序列而不是结果树的子节点是通过使用例如实现的。 xsl:variable as="item()*" ...
,而不是通过更改您的 xsl:evaluate
。
我有点困惑,因为这里有两个 XML 文档,它们都包含匹配 Description
的元素,但都没有匹配 Book/Descriptions/*
的元素,包含要计算的模式(表达式)的那个不包含 Book 元素。
也许您真正的错误被 copy/paste 错误掩盖了。您选择的变量名称 pattern
也暗示您可能会感到困惑:xsl:evaluate
的结果不是模式(甚至不是 XPath 表达式),它是一组节点。
一个明确的错误是您没有在变量上指定 as
属性(这意味着 xsl:evaluate 的结果被复制到新的文档树中)。我希望是这样的:
<xsl:variable name="selected-nodes" as="node()*">
<xsl:evaluate xpath="//Description/pattern" context-item="$root"/>
</xsl:variable>
但我不确定这是否正是您想要的,因为 //Description/pattern
选择了多个表达式,而 xsl:evaluate
只会计算一个。如果你想评估多个模式并合并结果,那是可以的,但我需要更清楚地了解需求。