XSLT - 带入与元素匹配的外部文档值

时间:2015-09-23 04:15:49

标签: xslt xslt-2.0

我有XML文件,我需要用外部文档中的值替换元素的值(idno [@type ='code'])。

我必须在该外部文件中匹配基于eISBN的值。

XML文件:

v19

外部文件(a2r-test.xml):

<book>
    <idno type="online">3456789012345</idno>
    <idno type="subject">Environment</idno>
    <idno type="subject">Water</idno>
    <idno type="subject">Policy</idno>
    <idno type="code">135/B</idno>
    <idno type="ID">43396</idno>
</book>

XSL:

<root>
    <row>
        <eISBN>1234567890123</eISBN>
        <uri>book1</uri>
        <a2r>89364</a2r>
    </row>
    <row>
        <eISBN>3456789012345</eISBN>
        <uri>book2</uri>
        <a2r>E135</a2r>
    </row>
    <row>
        <eISBN>5678901234567</eISBN>
        <uri>book3</uri>
        <a2r>B10765/B</a2r>
    </row>
</root>

我在xsl:value-of select中放入“a2r”的值(follow-sibling :: eISBN - 匹配idno [@ type ='online'])

最终预期结果:

<?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"
    xmlns:tei="http://www.tei-c.org/ns/1.0"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:variable name="a2r" select="document('a2r-test.xml')"/>

    <xsl:template match="tei:idno[@type='code']">
        <xsl:if test="$a2r//row/eISBN = preceding-sibling::tei:idno[@type='online']">
            <xsl:element name="idno">
                <xsl:attribute name="type" select="'code'"/>
                **<xsl:value-of select="?"/>**
            </xsl:element>
        </xsl:if>
    </xsl:template>

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

提前致谢。

1 个答案:

答案 0 :(得分:1)

通常,最好使用 key 来解决交叉引用。以下是匹配给定输入的示例:

XSLT 2.0

<xsl:stylesheet version="2.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:variable name="a2r-doc" select="document('a2r-test.xml')"/>

<xsl:key name="a2r-key" match="row" use="eISBN" />

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

<xsl:template match="idno[@type='code']">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:value-of select="key('a2r-key', ../idno[@type='online'], $a2r-doc)/a2r"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

注意

您没有向我们展示您的真实输入,从您的XSLT判断 - 是在命名空间中。在这种情况下,您不能对某些元素使用xsl:copy(通过身份转换模板)而对其他元素使用xsl:element(没有命名空间),否则您最终会得到的结果是不同的命名空间。