我需要根据它的父节点的属性来修改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,这有帮助,但我很难看到(如果我可以?)将其应用于动态值,取决于每个层次结构中的位置文本节点。
答案 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
您要尝试的内容达到。