如何在XSLT中组合XML同级

如何在XSLT中组合XML同级,xml,xslt,Xml,Xslt,我正在尝试使用XSLT组合两个同级节点值。我已经有了一个XSLT表,它已经组合了相同的节点,但是我很难弄清楚如何组合两个兄弟节点,而不会搞乱已经存在的内容 XML BB-1 1. 2. 电梯机房107 BB-1 1. 3. 电梯机房107 BB-1 1. 4. 电梯机房107 BB-1 1. 5. 电梯机房107 XSL , 输出应该是什么样子的: <?xml version="1.0" encoding="UTF-8"?> <root xmlns:fm="ht

我正在尝试使用XSLT组合两个同级节点值。我已经有了一个XSLT表,它已经组合了相同的节点,但是我很难弄清楚如何组合两个兄弟节点,而不会搞乱已经存在的内容

XML


BB-1
1.
2.
电梯机房107
BB-1
1.
3.
电梯机房107
BB-1
1.
4.
电梯机房107
BB-1
1.
5.
电梯机房107
XSL


, 
输出应该是什么样子的:

 <?xml version="1.0" encoding="UTF-8"?>
  <root xmlns:fm="http://www.filemaker.com/fmpdsoresult">
    <ROW xmlns="http://www.filemaker.com/fmpdsoresult">
      <Sign_Type>BB-1</Sign_Type>
      <fm:Location xmlns="">1-2, 1-3, 1-4, 1-5</fm:Location>
      <Line1>ELEVATOR MACHINE ROOM 107</Line1>
    </ROW>
  </root>

BB-1
1-2, 1-3, 1-4, 1-5
电梯机房107
任何人都可以帮我确定我需要在哪里和做什么改变才能让这一切顺利进行?
谢谢

也许这只是代码中的一个输入错误,但您的第一个模板与XML示例中不存在的元素FMPDSORESULT匹配

<xsl:template match="fm:FMPDSORESULT">

由于这与任何内容都不匹配,因此内置模板将应用,并且它们最终将使用与XML中四个元素中的每一个匹配fm:ROW的模板

您应该在根元素上进行匹配

<xsl:template match="root">

至于合并兄弟姐妹,我想您是说希望输出Floor元素和Location元素。例如,您可以在这里使用前面的兄弟姐妹

<xsl:value-of select="preceding-sibling::fm:Floor[1]" />

或者,这种语法也会起作用;只需获取当前父级的唯一Floor元素

<xsl:value-of select="../fm:Floor" />

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fm="http://www.filemaker.com/fmpdsoresult">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="artTypeNames" match="fm:ROW" use="concat(fm:Sign_Type, '||', fm:Line1)"/>
 <xsl:template match="root">
    <ROOT>
        <xsl:apply-templates select="fm:ROW[count(. | key('artTypeNames', concat(fm:Sign_Type, '||', fm:Line1))[1]) = 1]">
            <xsl:sort select="fm:Sign_Type" />
        </xsl:apply-templates>
    </ROOT>
 </xsl:template>

 <xsl:template match="fm:ROW">
        <xsl:copy>
            <xsl:apply-templates select="fm:Sign_Type" />

            <fm:Location>
                <xsl:apply-templates select="key('artTypeNames', concat(fm:Sign_Type,   '||', fm:Line1))/fm:Location" /> 
            </fm:Location>
            <xsl:apply-templates select="fm:Line1" />
        </xsl:copy>
</xsl:template>

<xsl:template match="fm:Location">
    <xsl:if test="position() &gt; 1">, </xsl:if>
    <xsl:value-of select="../fm:Floor" />
    <xsl:text>-</xsl:text>
    <xsl:value-of select="." />
</xsl:template>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>   

, 
-

也许这只是您代码中的一个输入错误,但是您的第一个模板与XML示例中不存在的元素FMPDSORESULT匹配

<xsl:template match="fm:FMPDSORESULT">

由于这与任何内容都不匹配,因此内置模板将应用,并且它们最终将使用与XML中四个元素中的每一个匹配fm:ROW的模板

您应该在根元素上进行匹配

<xsl:template match="root">

至于合并兄弟姐妹,我想您是说希望输出Floor元素和Location元素。例如,您可以在这里使用前面的兄弟姐妹

<xsl:value-of select="preceding-sibling::fm:Floor[1]" />

或者,这种语法也会起作用;只需获取当前父级的唯一Floor元素

<xsl:value-of select="../fm:Floor" />

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fm="http://www.filemaker.com/fmpdsoresult">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="artTypeNames" match="fm:ROW" use="concat(fm:Sign_Type, '||', fm:Line1)"/>
 <xsl:template match="root">
    <ROOT>
        <xsl:apply-templates select="fm:ROW[count(. | key('artTypeNames', concat(fm:Sign_Type, '||', fm:Line1))[1]) = 1]">
            <xsl:sort select="fm:Sign_Type" />
        </xsl:apply-templates>
    </ROOT>
 </xsl:template>

 <xsl:template match="fm:ROW">
        <xsl:copy>
            <xsl:apply-templates select="fm:Sign_Type" />

            <fm:Location>
                <xsl:apply-templates select="key('artTypeNames', concat(fm:Sign_Type,   '||', fm:Line1))/fm:Location" /> 
            </fm:Location>
            <xsl:apply-templates select="fm:Line1" />
        </xsl:copy>
</xsl:template>

<xsl:template match="fm:Location">
    <xsl:if test="position() &gt; 1">, </xsl:if>
    <xsl:value-of select="../fm:Floor" />
    <xsl:text>-</xsl:text>
    <xsl:value-of select="." />
</xsl:template>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>   

, 
-

是的,这是一个打字错误。我只是举了几个行元素作为例子。忘记了根元素。它也很好用,谢谢!是的,那是个打字错误。我只是举了几个行元素作为例子。忘记了根元素。它也很好用,谢谢!