xsl 1.0 代码创建一个不同的元素不起作用

问题描述 投票:0回答:2

我有这个 xsl 1.0 调用模板。 它采用两个 xml 元素,作为参数给出,并返回一个从两个参数创建的元素,但具有不同的元素。所有双打都应该被删除

<xsl:template name="distinctElements">
        <xsl:param name="xml1"/>
        <xsl:param name="xml2"/>
        
        <xsl:variable name="combined-nodes">
          <xsl:copy-of select="$xml1"/>
          <xsl:copy-of select="$xml2"/>
        </xsl:variable>
        
        <xsl:variable name="distinct-elements">
          <xsl:for-each select="$combined-nodes/*[not(. = preceding-sibling::*)]">
            <xsl:copy-of select="."/>
          </xsl:for-each>
        </xsl:variable>
        
        <xsl:for-each select="$distinct-elements/*">
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:template>

我的问题是,它不起作用。 具体来说,这段代码会产生问题:

<xsl:variable name="distinct-elements">
 <xsl:for-each select="$combined-nodes/*[not(. = preceding-sibling::*)]">
    <xsl:copy-of select="."/>
 </xsl:for-each>
</xsl:variable>

似乎根本无法遍历“$combined-nodes”。 如果我使用 $xml1 或 $xml2 而不是 $combined-nodes,则此代码片段有效。

我不明白。 有人在这里看到我的问题是什么吗?

谢谢你的帮助。

我用 $xml1 和 $xml2 交换了 $combined-nodes 并且代码有效。仅当使用组合元素时,代码不起作用。

编辑: 我研究了 muenchian 方法,并将对其进行更深入的研究。目前我真的不知道如何使它适应我的特殊情况。因为我要处理的 XML 非常通用:

<someuserdata>
  <item>
    <name>foo</name>
    <value>bar</value>
  </item>
  <item>
    <name>foo</name>
    <value>bar</value>
  </item>
  ...
</someuserdata>
<someappointmentdata>
  <item>
    <name>foo</name>
    <value>bar</value>
  </item>
  <item>
    <name>foo</name>
    <value>bar</value>
  </item>
  ...
</someappointmentdata> 

它包含来自不同数据库的具有不同信息的数据,所有这些数据都组合在一个 xml 文件中,嵌套在不同的级别。

xsl 以通用方式处理此 xml,只是通过检查某些“名称”-值而有所不同。

我尝试了 John Ernst 提供的代码示例,但无法正常工作。 我决定放弃调用模板的使用,并尝试减少代码以仅在我的代码的调用部分工作:

<xsl:template name="table_parent">  
        <xsl:param name="basis1" />
        <xsl:param name="basis2" />     
        <xsl:variable name="basis3">
            <xsl:copy-of select="xmlns:node-set($basis1 | $basis2)/*[not(. = preceding-sibling::*)]"/>
        </xsl:variable> 
        <xsl:for-each select="$basis3/*">

如您所见,我只是想遍历我的两个 xml 元素(basis1 和 basis2)的不同总和。

但即使是这条简单的线也行不通。我的前缀是 xmlns,我已经在这个例子中改变了它。

这不应该工作吗?

感谢您的耐心和帮助

编辑: 我这里有一些示例代码: XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="TEST.xsl"?>
<Root>
    <source1>
        <Zusatzinformation>
            <item>
                <Name>Bemerkung</Name>
                <Wert>yyy</Wert>
                <Attribut>NEU</Attribut>
            </item>
            <item>
                <Name>Versicherungsart</Name>
                <Wert>-kein Eintrag-</Wert>
                <Attribut>Unverändert</Attribut>
            </item>
            <item>
                <Name>Zusatzversichert</Name>
                <Wert>nein</Wert>
                <Attribut>Unverändert</Attribut>
            </item>
            <Anordner>
                <CTSmartMitarbeiter>
                    <CTSmartId>
                        <item>
                            <Name>ID</Name>
                            <Wert>-1</Wert>
                            <Attribut>Unverändert</Attribut>
                        </item>
                    </CTSmartId>
                </CTSmartMitarbeiter>
            </Anordner>
        </Zusatzinformation>
    </source1>
    <source2>
        <Zusatzinformation>
            <item>
                <Name>Versicherungsart</Name>
                <Wert>-kein Eintrag-</Wert>
                <Attribut>Unverändert</Attribut>
            </item>
            <item>
                <Name>Zusatzversichert</Name>
                <Wert>nein</Wert>
                <Attribut>Unverändert</Attribut>
            </item>
            <Anordner>
                <CTSmartMitarbeiter>
                    <CTSmartId>
                        <item>
                            <Name>ID</Name>
                            <Wert>-1</Wert>
                            <Attribut>Unverändert</Attribut>
                        </item>
                    </CTSmartId>
                </CTSmartMitarbeiter>
            </Anordner>
        </Zusatzinformation>
    </source2>
</Root>

xsl:

<?xml version="1.0" encoding="UTF-8"?>
<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:template match="/">
        <xsl:variable name="source1" select="//source1"/>
        <xsl:variable name="source2" select="//source2"/>

        <xsl:variable name="combined-nodes" select="$source1 | $source2"/>
        
        <xsl:variable name="distinct-elements" select="exsl:node-set($combined-nodes)"/>

        <xsl:variable name="basis3">
            <xsl:copy-of select="exsl:node-set($distinct-elements)/*[not(. = preceding-sibling::*)]"/>
        </xsl:variable> 

        <xsl:for-each select="basis3/*">
            <xsl:value-of select="."/><xsl:text> - </xsl:text>
        </xsl:for-each>

    </xsl:template>
</xsl:stylesheet>

xsl 应该只输出一个不同的列表:

Bemerkung 复习艺术 Zusatzversichert

谢谢大家。在您的帮助下,我找到了这个解决方案:

<xsl:template name="distinctElements">
  <xsl:param name="xml1"/>
  <xsl:param name="xml2"/>    
  
  <xsl:variable select="exsd:node-set($xml1|$xml2)" name="combined-nodes"/>   
  
  <xsl:variable name="result">
    <xsl:for-each select="$combined-nodes/item[count(. | key('item-by-name', Name)[1]) = 1]">
      <itemname><xsl:copy-of select="."/></itemname>          
    </xsl:for-each>
  </xsl:variable>         
 
  <xsl:copy-of select="$result"/>
</xsl:template>

因为我需要模板的输出作为节点集,所以我在调用后转换它:

<xsl:variable name="basis3Rtf">
    <xsl:call-template name="distinctElements">
        <xsl:with-param name="xml1" select="$basis1"/>
        <xsl:with-param name="xml2" select="$basis2"/>
    </xsl:call-template>
</xsl:variable>
<xsl:variable name="basis3" select="exsd:node-set($basis3Rtf)/itemname" />
<xsl:for-each select="$basis3/*">
xml xslt-1.0 xpath-1.0
2个回答
0
投票

考虑以下示例:

XML

<Root>
    <source1>
        <Zusatzinformation>
            <item>
                <Name>Bemerkung</Name>
                <Wert>yyy</Wert>
                <Attribut>NEU</Attribut>
            </item>
            <item>
                <Name>Versicherungsart</Name>
                <Wert>-kein Eintrag-</Wert>
                <Attribut>Unverändert</Attribut>
            </item>
            <item>
                <Name>Zusatzversichert</Name>
                <Wert>nein</Wert>
                <Attribut>Unverändert</Attribut>
            </item>
            <Anordner>
                <CTSmartMitarbeiter>
                    <CTSmartId>
                        <item>
                            <Name>ID</Name>
                            <Wert>-1</Wert>
                            <Attribut>Unverändert</Attribut>
                        </item>
                    </CTSmartId>
                </CTSmartMitarbeiter>
            </Anordner>
        </Zusatzinformation>
    </source1>
    <source2>
        <Zusatzinformation>
            <item>
                <Name>Versicherungsart</Name>
                <Wert>-kein Eintrag-</Wert>
                <Attribut>Unverändert</Attribut>
            </item>
            <item>
                <Name>Zusatzversichert</Name>
                <Wert>nein</Wert>
                <Attribut>Unverändert</Attribut>
            </item>
            <Anordner>
                <CTSmartMitarbeiter>
                    <CTSmartId>
                        <item>
                            <Name>ID</Name>
                            <Wert>-1</Wert>
                            <Attribut>Unverändert</Attribut>
                        </item>
                    </CTSmartId>
                </CTSmartMitarbeiter>
            </Anordner>
        </Zusatzinformation>
    </source2>
</Root>

使用(第一部分)Muenchian 分组:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:key name="item-by-name" match="item" use="Name" />

<xsl:template match="/Root">
    <xsl:for-each select="*/Zusatzinformation/item[count(. | key('item-by-name', Name)[1]) = 1]">
        <xsl:value-of select="Name"/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

结果

Bemerkung
Versicherungsart
Zusatzversichert

请注意,一些 XSLT 1.0 处理器支持

distinct()
扩展功能,这可以使这项任务变得更加容易。


0
投票

这是您可能会觉得有用的简化版本。

<!-- Call your template -->
<xsl:variable name="distinct">
  <xsl:call-template name="distinctElements">
    <xsl:with-param name="xml1" select="$test1"/>
    <xsl:with-param name="xml2" select="$test2"/>
  </xsl:call-template>
</xsl:variable>

<!-- Convert the RTF to a node-set.  Use your own prefix if not exsl. -->
<xsl:variable name="distinct-elements" select="exsl:node-set($distinct)"/>


<xsl:template name="distinctElements">
  <xsl:param name="xml1"/>
  <xsl:param name="xml2"/>

  <xsl:variable name="combined-nodes">
    <xsl:copy-of select="$xml1"/>
    <xsl:copy-of select="$xml2"/>
  </xsl:variable>

  <!-- Convert RTF to node-set.  -->
  <xsl:copy-of select="exsl:node-set($combined-nodes)/*[not(. = preceding-sibling::*)]"/>

</xsl:template>
© www.soinside.com 2019 - 2024. All rights reserved.