我有很大的 XML 文件,需要向其中注入处理指令。处理指令的位置被列为 xpath 位置。我创建了 XML 文件的小版本,以便在此处提供完整的示例。
这是一个小型 XML 示例文件:
<?xml version="1.0" encoding="UTF-8"?>
<ACT>
<TITLE>
<P>Some title</P>
</TITLE>
<LIST>
<ITEM>
<LABEL>Article 1</LABEL>
<P>Dummy text for article 1.</P>
</ITEM>
<ITEM>
<LABEL>Article 2</LABEL>
<P>Dummy text for article 2.</P>
<LIST>
<ITEM>
<LABEL>Article a</LABEL>
<P>Dummy text for article a.</P>
</ITEM>
<ITEM>
<LABEL>Article b</LABEL>
<P>Dummy text for article b.</P>
</ITEM>
<ITEM>
<LABEL>Article c</LABEL>
<P>Dummy text for article c.</P>
</ITEM>
</LIST>
</ITEM>
<ITEM>
<LABEL>Article 3</LABEL>
<P>Dummy text for article 3.</P>
</ITEM>
</LIST>
带有 xpath 位置的文件看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<report>
<page_break>
<description>NO 1</description>
<xpath_location>/ACT[1]/LIST[1]/ITEM[1]/P[1]</xpath_location>
</page_break>
<page_break>
<description>NO 2</description>
<xpath_location>/ACT[1]/LIST[1]/ITEM[2]/LIST[1]/ITEM[3]/P[1]</xpath_location>
</page_break>
</report>
我尝试使用 XSLT 3 xpath() 函数将当前元素的位置与 PageBreaks.xml 文件中的 xpath_location 元素进行匹配,但没有得到任何匹配项。当我将当前元素的 xpath() 放入消息中时,它在每个分支中都包含 Q{}。但是当我将它们添加到具有目标位置的文件中时,也没有给出任何结果。
这是我尝试过的XSL。希望有使用 xpath() 经验的人可以帮助我。交货截止日期是今天下午。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="3.0">
<xsl:output method="xml" encoding="UTF-8"/>
<xsl:variable name="breaks" as="node()" select="document('Breaks.xml')/report"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|text()">
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="mypath">
<xsl:value-of select="./path()"/>
</xsl:variable>
<xsl:variable name="pi_insert">
<xsl:if test="$breaks//xpath_location[. eq $mypath]">yes</xsl:if>
</xsl:variable>
<xsl:copy>
<xsl:apply-templates select="@*, node()"/>
</xsl:copy>
<xsl:if test="$pi_insert eq 'yes'">
<xsl:processing-instruction name="PAGE">
<xsl:value-of select="$breaks//xpath_location[. eq $mypath]/preceding-sibling::description"/>
</xsl:processing-instruction>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
看看这是否适合您:
XSLT 3.0
<xsl:stylesheet version="3.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="k1" match="page_break" use="xpath_location" />
<xsl:param name="breaks" select="document('Breaks.xml')"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="*">
<xsl:variable name="brk" select="key('k1', translate(path(), 'Q{}', ''), $breaks)" />
<xsl:next-match/>
<xsl:if test="$brk">
<xsl:processing-instruction name="PAGE">
<xsl:value-of select="$brk/description"/>
</xsl:processing-instruction>
</xsl:if>
</xsl:template>
</xsl:stylesheet>