[英]XSLT for sequence of child nodes in FOP
Using Apache FOP, I want to collect some info in a PDF file. 使用Apache FOP,我想收集PDF文件中的一些信息。 The XML source has some child nodes a to e, let's say
我们可以说XML源有一些子节点
<node>
<a>some val</a>
<b>some other val</b>
<c>more val</c>
<d>even more val</d>
<e>a last val</e>
</node>
I don't want to display all of them. 我不想显示所有这些。 a,b,c shall always be displayed but may be emtpy.
a,b,c应始终显示但可能是emtpy。 The maximum amount of displayed values is 3. So, d and e are optional and must be kept in that order.
最大显示值为3.因此,d和e是可选的,必须按此顺序保存。
Sadly, the XML structure cannot be modified. 遗憾的是,XML结构无法修改。
What is the right XSLT for that? 什么是正确的XSLT? I tried
我试过了
<xsl:for-each select="child::*[name()='a' or name() = 'b' or name() = 'c' or name() = 'd' or name() = 'e'][string-length(.)>0]">
<xsl:if test="position() <= 3">
<xsl:value-of select="name()"/>
</xsl:if>
</xsl:for-each>
but that doesn't bring me an ordered list. 但这并没有给我带来有序的清单。 :(
:(
<xsl:sort />
should hep. <xsl:sort />
应该是hep。
In your case it would be: 在你的情况下,它将是:
<xsl:sort select="name()"/>
Therefore try: 因此尝试:
<xsl:for-each select="child::*[name()='a' or name() = 'b' or name() = 'c' or name() = 'd' or name() = 'e'][string-length(.)>0]">
<xsl:sort select="name()"/>
<xsl:if test="position() <= 3">
<xsl:value-of select="name()"/>
</xsl:if>
</xsl:for-each>
Update: Because in real live input XML there is not useful information to sort by you may add some meta information. 更新:因为在实际输入XML中没有有用的信息可以排序,您可以添加一些元信息。 Where to store the meta information depend on the capabilities of the xslt processor.
存储元信息的位置取决于xslt处理器的功能。
If you can use the node-set() extension you may try something like this: 如果你可以使用node-set()扩展,你可以尝试这样的事情:
Add a variable to stylesheet with expected order. 使用预期顺序向样式表添加变量。
xsl:variable name="myOrder">
<order name="a" pos="1" />
<order name="b" pos="3" />
<order name="c" pos="2" />
<order name="d" pos="4" />
<order name="e" pos="5" />
</xsl:variable>
Make this variable usable as node-set by: 使此变量可用作节点设置:
<xsl:variable name="Order" select="exsl:node-set($myOrder)" />
Sort with help of this variable. 借助此变量排序。
<xsl:sort select="$Order/order[@name= name(current())]/@pos"/>
@Florian Ruh, your stated requirement is not self-consistent: "I don't want to display all of them. a,b,c shall always be displayed. The maximum amount of displayed values is 3. So, d and e are optional and must be kept in that order." @Florian Ruh,你声明的要求不是自洽的:“我不想显示所有这些要求。应始终显示a,b,c。显示的最大值为3.因此,d和e是可选的,必须按顺序保留。“
If a, b and c are always displayed, and the maximum number of displayed values is 3, then there is no chance for d and 3 to be displayed. 如果始终显示a,b和c,并且显示的最大值数为3,则不会显示d和3。
Please clarify your requirement. 请澄清您的要求。
Note that it is very poor form to use the name() function as you have. 请注意,使用name()函数的形式非常糟糕。
The equivalent to: 相当于:
<xsl:for-each select="child::*[name()='a' or name() = 'b' or name() = 'c' or name() = 'd' or name() = 'e'][string-length(.)>0]">
is: 是:
<xsl:for-each select="(a|b|c|d|e)[string(.)]">
... and the approach I posit is namespace-safe, while the approach you used is not. ...我假设的方法是命名空间安全的,而你使用的方法则不是。
Perhaps I am not understanding correctly, but if you want to only return the first three items into an ordered list, you could do something like 也许我没有正确理解,但如果你只想将前三个项目归还有序列表,你可以做类似的事情
<xsl:template match="node">
<fo:list-block>
<xsl:apply-templates/>
</fo:list-block>
</xsl:template>
And 和
<xsl:template match="node/*[4] | node/*[5]"/>
<xsl:template match="node/*[1] | node/*[2] | node/*[3]">
<fo:list-item>
<fo:list-item-label>
<fo:block><xsl:value-of select="position()"/></fo:block>
</fo:list-item-label>
<fo:list-item-body>
<fo:block><xsl:value-of select="."/></fo:block>
</fo:list-item-body>
</fo:list-item>
</xsl:template>
This will ignore any 4th and 5th elements, but process the first, second, and third in document order (since that's the order in which they are encountered). 这将忽略任何第4和第5个元素,但按文档顺序处理第一个,第二个和第三个元素(因为这是它们遇到的顺序)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.