如何使用 XSLT 3 中的 xpath() 将元素推送到 XML 中?

问题描述 投票:0回答:1

我有很大的 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>
xml xpath xslt
1个回答
0
投票

看看这是否适合您:

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>
© www.soinside.com 2019 - 2024. All rights reserved.