Фильтровать записи XML, если значение существует в другом списке XML

У меня есть два основных XML XMls и XML списка. Я пытаюсь фильтровать основной XML на основе наличия одинакового значения узла в обоих XML.

Пробовал ниже xslt, но не работает, как ожидалось.

XSLT

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="2.0">
    <xsl:output method="xml" omit-xml-declaration="yes" media-type="string"/>

<xsl:param name="cc" select="'list.xml'"/>
<xsl:variable name="list" select="document($cc)/rows/row" />

<xsl:template match="/lines">
<xsl:copy>
    <xsl:apply-templates select="/line[substring-before(/account/seg1, ' ')=$list/cc]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

Я использую инструмент Cast Iron для выполнения этого фильтра, он поддерживает XSLT 2.0

Основной xml:

<lines>
  <line>
        <account>
            <seg1>0101 Expense</seg1>
    </account>
 </line>
 <line>
    <account>
        <seg1>0102 Capital</seg1>
    </account>
 </line>
 <line>
    <account>
        <seg1>0103 Expense</seg1>
    </account>
 </line>
 <line>
    <account>
        <seg1>0104 Expense</seg1>
    </account>
 </line>
 <line>
    <account>
        <seg1>0105 Espense</seg1>
    </account>
 </line>
</lines>

Список Xml:

<rows>
 <row>
    <cc>0101</cc>
 </row>
 <row>
    <cc>0103</cc>
 </row>
 <row>
    <cc>0105</cc>
 </row>
 <row>
    <cc>0107</cc>
 </row>
 <row>
    <cc>0109</cc>
 </row>
</rows>

выходной Xml:

<lines>
 <line>
    <account>
        <seg1>0101</seg1>
    </account>
 </line>
 <line>
    <account>
        <seg1>0103</seg1>
    </account>
 </line>
 <line>
    <account>
        <seg1>0105</seg1>
    </account>
 </line>
</lines>

EDIT1: добавил xslt я пытаюсь и inputxml с дополнительной информацией.

1 ответ

Объявить ключ <xsl:key name="ref" match="row/cc" use="."/> а затем использовать шаблон преобразования идентификаторов плюс пустой шаблон

<xsl:template match="line[not(key('ref', account/seg1, doc('list.xml')))]"/>

После редактирования, где вы существенно изменили структуру ввода, я думаю, что предложенный подход все еще будет работать, если вы измените пустой шаблон на

<xsl:template match="line[not(key('ref', substring-before(account/seg1, ' '), doc('list.xml')))]"/>
Другие вопросы по тегам