【问题标题】:Compare two nodes based on child nodes from different xml using xslt使用 xslt 基于来自不同 xml 的子节点比较两个节点
【发布时间】:2014-06-17 15:54:47
【问题描述】:

我有两个 XML:-

  1. keylist.xml

    <?xml version="1.0" encoding="UTF-8"?><jdbcGeneralActivityOutput>
    <unknownResultset>
        <row>
            <column>
                <name>SRC_SYS_ID</name>
                <value>10015</value>
            </column>
            <column>
                <name>SRC_SYS_RCRD_ID_VAL</name>
                <value>3327853</value>
            </column>
        </row>
        <row>
            <column>
                <name>SRC_SYS_ID</name>
                <value>10015</value>
            </column>
            <column>
                <name>SRC_SYS_RCRD_ID_VAL</name>
                <value>9751818</value>
            </column>
        </row>
        <row>
            <column>
                <name>SRC_SYS_ID</name>
                <value>10015</value>
            </column>
            <column>
                <name>SRC_SYS_RCRD_ID_VAL</name>
                <value>9883123</value>
            </column>
        </row>
        <row>
            <column>
                <name>SRC_SYS_ID</name>
                <value>10015</value>
            </column>
            <column>
                <name>SRC_SYS_RCRD_ID_VAL</name>
                <value>9901061</value>
            </column>
        </row>
    </unknownResultset>    </jdbcGeneralActivityOutput>
    

和第二个 XML 2. CurrentRow.xml

    <?xml version="1.0" encoding="UTF-8"?>
<row>
    <column>
        <name>SRC_SYS_ID</name>
        <value>10015</value>
    </column>
    <column>
        <name>SRC_SYS_RCRD_ID_VAL</name>
        <value>3327853</value>
    </column>
    <column>
        <name>PRTY_STTS_CDV</name>
        <value>A</value>
    </column>
    <column>
        <name>PRTY_DSPLY_NM</name>
        <value>ALEGRIA BRAZILIAN GRILL</value>
    </column>
    <column>
        <name>ADDR_LN_1_TXT</name>
        <value>24449 KATY FRWY SUITE 500</value>
    </column>
    <column>
        <name>ADDR_LN_2_TXT</name>
        <value/>
    </column>
    <column>
        <name>ADDR_LN_3_TXT</name>
        <value/>
    </column>
</row>

我想要做的是找出 keylist.xml 中的完整行(一行中的所有名称值对都应该匹配)是否存在于 currentRow.xml 中。

这是我迄今为止尝试过的......但没有运气。谁能帮帮我

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:param name="currentRow" select="document('C:\Personal\09086559\Desktop\Xmls\currentRow.xml')"/>
    <!--<xsl:param name="TargetPrimaryKeys" select="document('C:\Personal\09086559\Desktop\Xmls\temp5.xml')"/>
    -->
    <xsl:template match="/">
        <xsl:variable name="apos">'</xsl:variable>
        <xsl:for-each select="jdbcGeneralActivityOutput/unknownResultset/row">
            <xsl:for-each select="column">
                <xsl:variable name="currentName" select="current()/name"/>
                <xsl:variable name="currentValue" select="current()/value"/>
                <xsl:for-each select="$currentRow/row/column">
                    <xsl:if test="current()/name=$currentName and current()/value=$currentValue">Y</xsl:if>
                    <!--<xsl:value-of select="$currentName"/>
                    <xsl:value-of select="$currentValue"/>
                    -->
                </xsl:for-each>
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 您能否澄清 (a) XSLT 正在处理哪个文档,以及 (b) 预期结果是什么?
  • keylist.xml 由 XSLT 处理,currentRow.xml 作为参数传递,但它是开放的,如果需要,我也可以反转它。上述情况下的预期输出应该只是“Y " 因为 keylist.xml 的第一个 中的列(名称/值)在 currentRow.xml 中也可用。如果没有一个 匹配,那么我期望输出为“N”
  • 所以整个输入只有一个全局“是”或“否”结果?
  • 是的。只是想找出 keylist.xml 中的任何行是否存在于 currentRow.xml 中

标签: xml xslt


【解决方案1】:

Vivek 的原始答案似乎还可以。您可以将 for-each 更改为 apply-templates 并将输出修改为比 Y 更清晰的内容。该程序只是比较两个 XML 中的所有元素 column 以查找它们是否相同。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:template match="column">
<xsl:variable name="currantName" select="name"/>
<xsl:variable name="currantValue" select="value"/>
 <xsl:for-each select="document('currentNode.xml')//column"><!--modify your PATH to currentNode.xml-->
 <xsl:if test="(./name/text() = $currantName) and (./value/text() = $currantValue) ">
 YES, found the element
 <xsl:copy-of select="."/>
from  currentNode.xml   in keylist.xml.
 </xsl:if>
 </xsl:for-each>

</xsl:template>

<xsl:template match="row">
<root>
<xsl:apply-templates/>
Search is over. All possible matches should be listed above.
</root>
</xsl:template>
</xsl:stylesheet>

【讨论】:

    【解决方案2】:

    这样怎么样?

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:param name="currentRow" select="document('C:\Personal\09086559\Desktop\Xmls\currentRow.xml')"/>
    
    <xsl:key name="col" match="column" use="concat(name, '|', value)" />
    
    <xsl:template match="/">
        <xsl:variable name="keyvals">
            <xsl:for-each select="$currentRow/row/column">
                <keyval><xsl:value-of select="concat(name, '|', value)" /></keyval>
            </xsl:for-each>
        </xsl:variable>
        <output>
            <xsl:choose>
                <xsl:when test="key('col', exsl:node-set($keyvals)/keyval)">yes</xsl:when>
                <xsl:otherwise>no</xsl:otherwise>
            </xsl:choose>
        </output>
    </xsl:template>
    
    </xsl:stylesheet>
    

    编辑:

    如果我正确理解您的说明,即“是”意味着至少有一行的列在另一文档中都有匹配的列,然后尝试:

    <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:param name="currentRow" select="document('C:\Personal\09086559\Desktop\Xmls\currentRow.xml')"/>
    
    <xsl:template match="/">
        <xsl:variable name="keyvals">
            <xsl:for-each select="$currentRow/row/column">
                <keyval><xsl:value-of select="concat(name, '|', value)" /></keyval>
            </xsl:for-each>
        </xsl:variable>
        <output>
            <xsl:choose>
                <xsl:when test="jdbcGeneralActivityOutput/unknownResultset/row[count(column) = count(column[concat(name, '|', value)=exsl:node-set($keyvals)/keyval])]">yes</xsl:when>
                <xsl:otherwise>no</xsl:otherwise>
            </xsl:choose>
        </output>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 非常感谢迈克尔,但我收到此错误“命名空间'exslt.org/common'不包含任何功能”有什么想法吗?
    • @Vivek,您使用哪种 XSLT 处理器?
    • 我改成 saxon-B 并且能够运行它,但是我总是没有得到任何输出。
    • 我知道出了什么问题,即使当前行中存在 keylist 中的名称/值对之一,输出也会出现。我想要的是,只有当 keylist.xml 中 的所有名称/值对都存在于 currentRow.xml 中时,它才应该给出 yes
    • @Vivek 是哪一个? "只想知道 keylist.xml 中的 any 行是否存在于 currentRow.xml 中" OR "只有当 all keylist.xml 中 的名称/值对出现在 currentRow.xml 的 中时,它才应该给出 yes"
    猜你喜欢
    • 2021-02-04
    • 2017-01-13
    • 2021-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多