2

需要明确的是,我已经找到了一种方法来完成我想要使用 XSLT 完成的任务,但它让我觉得效率很低,我想看看是否可以使用不同的解决方案,因为它有助于编写未来的样式表。

另外,我真诚地为以下段落的冗长道歉。

至少,我试图从用俄语编写并以 XML 编码的故事中提取('pavlova.xml' - 不幸的是,文件太大而无法与我的问题一起发布,但这不是完全必要的)数据,这对在 SVG 中生成饼图。我试图将这些数据存储在一个名为 $chartData 的变量中。给定的饼图总体上与目标角色(一个参数)相关,饼图中的每个单独块将代表一个说话者(另一个角色),它们的大小表示每个说话者相对于其他说话者所说的目标字符的多少。我首先遍历所有说话者(任何提到目标角色的角色),然后确定角色名字在特定说话者的演讲中出现的次数。然而,这些值仅对提到该角色的总次数有用。我需要总数来计算百分比以生成饼图。我知道我可以在另一个变量中单独计算它,但我有兴趣看看我是否可以将一系列节点存储在一个变量中。单独计算总和似乎很浪费,因为它遍历的路径几乎与找到单个计数的路径相同,在这些路径中,在检索到单个值后将它们相加会更有效。到目前为止,我已经能够计算出我想要的一切,但是我尝试使用 xsl:for-each 迭代一个变量,并让它将我的变量识别为一个序列。我需要总数来计算百分比以生成饼图。我知道我可以在另一个变量中单独计算它,但我有兴趣看看我是否可以将一系列节点存储在一个变量中。单独计算总和似乎很浪费,因为它遍历的路径几乎与找到单个计数的路径相同,在这些路径中,在检索到单个值后将它们相加会更有效。到目前为止,我已经能够计算出我想要的一切,但是我尝试使用 xsl:for-each 迭代一个变量,并让它将我的变量识别为一个序列。我需要总数来计算百分比以生成饼图。我知道我可以在另一个变量中单独计算它,但我有兴趣看看我是否可以将一系列节点存储在一个变量中。单独计算总和似乎很浪费,因为它遍历的路径几乎与找到单个计数的路径相同,在这些路径中,在检索到单个值后将它们相加会更有效。到目前为止,我已经能够计算出我想要的一切,但是我尝试使用 xsl:for-each 迭代一个变量,并让它将我的变量识别为一个序列。单独计算总和似乎很浪费,因为它遍历的路径几乎与找到单个计数的路径相同,在这些路径中,在检索到单个值后将它们相加会更有效。到目前为止,我已经能够计算出我想要的一切,但是我尝试使用 xsl:for-each 迭代一个变量,并让它将我的变量识别为一个序列。单独计算总和似乎很浪费,因为它遍历的路径几乎与找到单个计数的路径相同,在这些路径中,在检索到单个值后将它们相加会更有效。到目前为止,我已经能够计算出我想要的一切,但是我尝试使用 xsl:for-each 迭代一个变量,并让它将我的变量识别为一个序列。

我希望变量的格式是这样的:

<count name="$speaker1>
    <xsl:value-of select="$spokenCount1"/>
</count>
<count name="$speaker2>
    <xsl:value-of select="$spokenCount2"/>
</count>
...

我尝试了很多方法来解决这个问题,但我不确定是否可以解决。首先是使用 @as 属性更准确地定义 xsl:variable 的内容(特别是尝试将其内容定义为序列),但我发现很难找到和理解有关该属性的文档以及 SequenceType 的工作方式. 其次,我尝试研究如何将内容放入变量中(直接将 for-each 放入变量中并使用 xsl:value-of 或 xsl:copy-of,而不是声明变量并使用 xsl:copy-在外部 for-each 中将数据附加到变量中)。

似乎 xsl:copy-of,而不是 xsl:sequence(具有讽刺意味)是我需要附加一系列节点的东西。我只能使用以下代码获得我上面描述的格式:

<xsl:variable name="chartData"/>
    <xsl:for-each
        select="distinct-values(//speech[.//name[not(parent::nonspeech) and ./@ref eq $character]]/@speaker)">
        <xsl:copy-of select="$chartData"/>
        <xsl:variable name="speaker" select="current()"/>
        <xsl:variable name="spokenCount"
            select="document('pavlova.xml')/count(//speech[@speaker eq $speaker]//name[not(parent::nonspeech) and ./@ref eq $character])"/>
        <count name="{$speaker}">
            <xsl:value-of select="$spokenCount"/>
        </count>
    </xsl:for-each>
    <xsl:variable name="spokenTotal" select="sum($chartData)"/>
    <xsl:value-of select="$chartData"/>
    <!--xsl:for-each select="$chartData/count">
        ...
    </xsl:for-each-->

最终目标是让底部注释掉的 for-each 循环遍历每个计数元素,而不是给我一个错误。我的问题是,如果变量如下所示,我可以将变量视为 XML 并遍历每个 count 元素,还是始终将其视为字符串?

<?xml version="1.0" encoding="UTF-8"?>
<count name="young-man">4</count>
<count name="olga">24</count>
<count name="cecilija">34</count>
<count name="blonde">1</count>
<count name="vera">32</count>
<count name="servant-fem">6</count>
<count name="valickaja">20</count>
<count name="muse">66</count>
<count name="viktor">4</count>
<count name="dmitrij">15</count>
<count name="anna">11</count>
<count name="iličev">3</count>
<count name="narod">1</count>
<count name="society-man">3</count>

如果是这样,怎么办?

另外,如果有人可以解释,为什么 xsl:copy-of 仅在我将 for-each 超出变量范围并将 select 设置为“$chartData”时进行深度复制?如果我尝试在变量中使用 xsl:copy-of,它只会复制文字元素的文本内容<count>并创建一个字符串:424341326206641511313)。

4

1 回答 1

2

恐怕你的问题很混乱。你想做的事情并不难,但很难知道从哪里开始帮助你前进。

我有兴趣看看是否可以将节点序列存储在变量中

是的你可以。您需要清楚是否要创建新节点,或者是否希望变量保存对现有节点的引用。在第一种情况下,您使用“临时树”构造:

<xsl:variable name="tree">
  ... content ...
</xsl:variable>

在第二种情况下,您可以使用 select 属性,或包含的序列构造函数加上“as”属性:

<xsl:variable name="seq" select="expression"/>

或者

<xsl:variable name="seq" as="node()*">
  ... content ...
</xsl:variable>

我正在尝试使用 xsl:for-each 迭代变量并让它将我的变量识别为序列

好吧,每个变量的值都是一个序列,问题是,序列中有什么?如果您使用上述变量的第一种形式(内容,没有作为属性),则序列将是包含单个文档节点的单例序列;您可能希望使用路径表达式导航到其子项,例如<xsl:for-each select="$tree/*"/>. 在第二种和第三种情况下,序列通常包含多个节点,可以是任何类型的节点,因此您更有可能编写<xsl:for-each select="$seq"/>.

我发现很难找到和理解有关该属性的文档以及 SequenceType 的工作原理

你在哪里看的?我不能把我的书《XSLT 2.0 Programmer's Reference》推荐得太高...我认为你是那种想要了解事物真正如何工作的人,而不是通过从示例中反复试验来学习。这本书就是为这样的人写的。

似乎 xsl:copy-of,而不是 xsl:sequence(具有讽刺意味)是我需要附加一系列节点的东西。

不,你错了。如果要创建包含对现有节点的引用的变量,则需要 xsl:sequence。如果您正在创建一个包含节点副本的临时树,那么 xsl:sequence 和 xsl:copy-of 具有完全相同的效果 - 两者都将复制选定的节点。

我可以将变量视为 XML 并遍历每个 count 元素,如果它如下所示

是的你可以。但是我们无法从您对序列的表示中判断这些节点是否是文档节点的子节点,并且知道这一点至关重要。

为什么 xsl:copy-of 仅在我将 for-each 超出变量范围并将 select 设置为“$chartData”时进行深度复制?如果我尝试在变量中使用 xsl:copy-of 它只会复制文字元素的文本内容并创建一个字符串

你在这里得出了一个错误的推论。xsl:copy-of 总是做一个深拷贝。如果您只看到节点的字符串内容,那是因为正在使用后续操作来原子化节点或提取它们的字符串值。

于 2012-07-18T08:19:00.183 回答