根据父标记属性修改xml属性

时间:2014-05-09 16:00:11

标签: xml xslt

我需要根据它的父节点的属性来修改XML节点的属性。

我认为用例子更好地解释......所以:

我有一个xml文件,如下所示:

<pdf2xml>
    <page number="1">
        <text top="100" />
    </page>
    <page number="2">
        <text top="100" />
        <text top="50" />
    </page>
</pdf2xml>

我目前正在使用以下xslt模板在每个页面中按“顶部”排序文本节点:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">     

    <xsl:template match="node()|@*">
        <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
    </xsl:template>

    <xsl:template match="pdf2xml/page">
        <xsl:copy>
            <xsl:for-each select=".">
                <xsl:apply-templates select="*">
                    <xsl:sort select="@top" data-type="number"/>
                </xsl:apply-templates>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

但是,我稍后使用getElementsByTagName("text")将所有文本节点称为一个长数组 - 所以我想要做的是make text@[top] = 5000 * page@[number] - 以便我的所有文本top属性顺序通过整个文件。

我看了this question,这有帮助,但我很难看到(如果我可以?)将其应用于动态值,取决于每个层次结构中的位置文本节点。

1 个答案:

答案 0 :(得分:3)

我使用匹配top属性本身的模板,您可以在其中将页码引用为../../@number(在XPath中,属性节点不是其包含元素的子元素,但是包含元素属性节点的父节点:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="node()|@*">
        <xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
    </xsl:template>

    <xsl:template match="pdf2xml/page">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:apply-templates select="*">
                <xsl:sort select="@top" data-type="number"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="text/@top">
        <xsl:attribute name="top">
            <xsl:value-of select=". + (../../@number * 5000)" />
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

您可能更愿意使用ancestor::page[1]/@number代替../../@number使事情变得更明确,以便让代码的未来读者更清楚地了解它最接近的page您要尝试的内容达到。