【问题标题】:Matching and filtering nodes with contains() in XSLT 2.0在 XSLT 2.0 中使用 contains() 匹配和过滤节点
【发布时间】:2014-01-22 12:37:44
【问题描述】:

我有一组关于人的 XML 记录,这些记录对与其他人以及相关资源(书籍等)的关系进行编码。基本结构是这样的:

<record>
    <name>Smith, Jane</name>
    <relations>
        <relation>Frost, Robert, 1874-1963</relation>
        <relation>Jones, William</relation>            
        <resource>
            <title>Poems</title>
            <author>Frost, Robert</author>
        </resource>
        <resource>
            <title>Some Title</title>
            <author>Author, Some</author>
        </resource>
    </relations>
</record>

我需要在“拉”式 XSLT 2.0 样式表中处理这个问题,这样我就能够过滤掉包含或以后面 &lt;author&gt; 节点中的文本开头的 &lt;relation&gt; 节点。两者不会完全匹配,因为&lt;relation&gt; 节点包含额外的文本,通常是出生日期和死亡日期。

我最初的冲动是尝试使用一对xsl:for-each 循环来测试节点值,但这不起作用。这个示例样式表...

<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:template match="/">
        <test>
            <xsl:for-each select="record/relations/relation">
                <xsl:variable name="relation" select="."/>
                <xsl:for-each select="../resource/author">
                    <xsl:variable name="resource" select="."/>
                    <relation>
                        <xsl:value-of select="$relation[not(contains(.,$resource))]"/>
                    </relation>
                </xsl:for-each>
            </xsl:for-each>
        </test>
    </xsl:template>
</xsl:stylesheet>

...给我:

<test>
    <relation/>
    <relation>Frost, Robert, 1874-1963</relation>
    <relation>Jones, William</relation>
    <relation>Jones, William</relation>
</test>

但我真正想要的只是:

<test>
    <relation>Jones, William</relation>
</test>

如何比较这两个节点集并仅过滤掉匹配的节点?同样,我需要在现有的“拉”式样式表中执行此操作,该样式表只有一个xsl:template,与文档根匹配。提前致谢!

【问题讨论】:

    标签: xml xslt xpath xslt-2.0 xpath-2.0


    【解决方案1】:

    我认为您可以在单个 XPath 2.0 "quantified expression" 中执行此操作,基本上您正在寻找所有 relation 元素,例如

    not(some $author in following::author satisfies contains(., $author))
    

    如果您想在每个单独的 relations 块中保留检查,您可以使用 ../resource/author 而不是 following::author

    XSLT 示例:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:output method="xml" indent="yes" />
    
      <xsl:template match="/">
        <test>
          <xsl:sequence select="record/relations/relation[
           not(some $author in following::author satisfies contains(., $author))]" />
        </test>
      </xsl:template>
    
    </xsl:stylesheet>
    

    输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <test>
       <relation>Jones, William</relation>
    </test>
    

    【讨论】:

      猜你喜欢
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2021-03-21
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多