简体   繁体   English

FOP中子节点序列的XSLT

[英]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(.)&gt;0]">
    <xsl:if test="position() &lt;= 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(.)&gt;0]">
        <xsl:sort select="name()"/>
        <xsl:if test="position() &lt;= 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(.)&gt;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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM