如果同级节点的子节点存在XSLT,则父节点输出

时间:2018-08-12 04:45:22

标签: xml xslt

我需要获得一个父节点的输出,该父节点在另一个XML文件中具有与某个元素相同的内容。我是XSLT的新手,所以希望您能帮助我指出我的错误。

这是我的外部xml:“ XML2.xml”

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <section>
        <sub-section>
            <chapter>Chapter 1</chapter>
        </sub-section>
        <sub-sectionB>
            <author>Author 1A</author>
            <author>Author 2B</author>
        </sub-sectionB> 
    </section>
    <section>
        <sub-section>
            <chapter>Chapter 2</chapter>
        </sub-section>
        <sub-sectionB>
            <author>Author 1D</author>
            <author>Author 2C</author>
        </sub-sectionB> 
     </section>
</root>

我的主要XML:XML1.xml

    <?xml version="1.0" encoding="UTF-8"?>
<rules>
    <somerules>
        <rule1>Author 1A</rule1>
    </somerules>
    <somerules>
        <rule1>Author 1C</rule1>
    </somerules>
</rules>

我的XSLT尝试:XMLRULES.xslt

?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="2.0">

    <xsl:param name="xinput" select="document('XML2.xml')"/>

    <xsl:template match="/">
        <xsl:variable name="var1" select="$xinput/root/section/sub-sectionB/author"/>            
            <xsl:for-each select="/rules/somerules/rule1[(.=$var1)]">
                <xsl:value-of select="$xinput/root/section/sub-section/chapter"/>
            </xsl:for-each>

    </xsl:template>

</xsl:stylesheet>

当前HTML输出:

Chapter1 Chapter2

我想要的HTML输出是获取文本:

Chapter1

来自子节节点if Author1A (from XML1 file) = Author 1A (from XML2 file)

我现在得到的是所有章节的列表。我如何才能获得Chapter1?

1 个答案:

答案 0 :(得分:1)

对于交叉引用,我将使用xsl:key设置密钥(https://www.w3.org/TR/xslt-30/#key)并使用key函数,尤其是在您似乎正在使用XSLT 2的情况下,使用该函数的第三个参数传递要搜索的子树或文档。

因此键定义可能是

  <xsl:key name="chapter-ref" match="section/sub-section/chapter" use="../../sub-sectionB/author"/>

然后您只需选择

  <xsl:value-of select="key('chapter-ref', rules/somerules/rule1, $doc2)"/>

完整的样式表应该是

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

  <xsl:param name="doc2">
<root>
    <section>
        <sub-section>
            <chapter>Chapter 1</chapter>
        </sub-section>
        <sub-sectionB>
            <author>Author 1A</author>
            <author>Author 2B</author>
        </sub-sectionB> 
    </section>
    <section>
        <sub-section>
            <chapter>Chapter 2</chapter>
        </sub-section>
        <sub-sectionB>
            <author>Author 1D</author>
            <author>Author 2C</author>
        </sub-sectionB> 
     </section>
</root>
  </xsl:param>

  <xsl:key name="chapter-ref" match="section/sub-section/chapter" use="../../sub-sectionB/author"/>

  <xsl:template match="/">
      <xsl:value-of select="key('chapter-ref', rules/somerules/rule1, $doc2)"/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pPqsHTE/1上在线,第二个文档在此在线是为了简化示例,但是您当然也可以使用<xsl:param name="doc2" select="doc('xml2.xml')"/>