简体   繁体   English

Apply-Template 仅适用于 ID 基于父子节点列表的节点

[英]Apply-Template only for nodes with ID based on parent subnode list

I'm fairly new to XSLT and trying to solve a problem with a complex XML.我对 XSLT 很陌生,并试图解决复杂的 XML 的问题。 Here is an example on the XML and the output wanted.这是 XML 和 output 的示例。

Problem is that I need to select Identity based on the Order 's IdentityOrder .问题是我需要 select Identity基于OrderIdentityOrder The compare should be done on IdentityId .比较应该在IdentityId上完成。

The Order should not be included in the list if the Identity's LastName is Empty如果身份的LastName为空,则订单不应包含在列表中

As you can see from my experiment, I can make this work with the transformation, but I'm not able to figure out how to exclude the orders where Identity's LastName is empty.正如您从我的实验中看到的那样,我可以通过转换来完成这项工作,但我无法弄清楚如何排除 Identity 的 LastName 为空的订单。

Appreciate all help I can get;)感谢我能得到的所有帮助;)

<Orders>
    <Order>
        <OrderNo>OR1</OrderNo>
        <BookingHeader>
            <BookingHeaderID>1</BookingHeaderID>
            <Identities>
                <Identity>
                    <IdentityId>1</IdentityId>
                    <FirstName>John</FirstName>
                    <LastName>Doe</LastName>
                </Identity>
                <Identity>
                    <IdentityId>2</IdentityId>
                    <FirstName>Petter</FirstName>
                    <LastName>Smart</LastName>
                </Identity>
                <Identity>
                    <IdentityId>3</IdentityId>
                    <FirstName>Betty</FirstName>
                    <LastName>Blue</LastName>
                </Identity>
            </Identities>
        </BookingHeader>
        <IdentityOrders>
            <IdentityOrder>
                <IdentityId>1</IdentityId>
                <Name>John Doe</Name>
            </IdentityOrder>
        </IdentityOrders>
    </Order>
    <Order>
        <OrderNo>OR2</OrderNo>
        <BookingHeader>
            <BookingHeaderID>1</BookingHeaderID>
            <Identities>
                <Identity>
                    <IdentityId>1</IdentityId>
                    <FirstName>John</FirstName>
                    <LastName>Doe</LastName>
                </Identity>
                <Identity>
                    <IdentityId>2</IdentityId>
                    <FirstName>Petter</FirstName>
                    <LastName>Smart</LastName>
                </Identity>
                <Identity>
                    <IdentityId>3</IdentityId>
                    <FirstName>Betty</FirstName>
                    <LastName>Blue</LastName>
                </Identity>
            </Identities>
        </BookingHeader>
        <IdentityOrders>
            <IdentityOrder>
                <IdentityId>1</IdentityId>
                <Name>John Doe</Name>
            </IdentityOrder>
            <IdentityOrder>
                <IdentityId>3</IdentityId>
                <Name>Betty Blue</Name>
            </IdentityOrder>
        </IdentityOrders>
    </Order>
    <Order>
        <OrderNo>OR3</OrderNo>
        <BookingHeader>
            <BookingHeaderID>1</BookingHeaderID>
            <Identities>
                <Identity>
                    <IdentityId>1</IdentityId>
                    <FirstName>John</FirstName>
                    <LastName>Doe</LastName>
                </Identity>
                <Identity>
                    <IdentityId>2</IdentityId>
                    <FirstName>Petter</FirstName>
                    <LastName></LastName>
                </Identity>
                <Identity>
                    <IdentityId>3</IdentityId>
                    <FirstName>Betty</FirstName>
                    <LastName>Blue</LastName>
                </Identity>
            </Identities>
        </BookingHeader>
        <IdentityOrders>
            <IdentityOrder>
                <IdentityId>2</IdentityId>
                <Name>Petter</Name>
            </IdentityOrder>
            <IdentityOrder>
                <IdentityId>3</IdentityId>
                <Name>Betty Blue</Name>
            </IdentityOrder>
        </IdentityOrders>
    </Order>
    <Order>
        <OrderNo>OR4</OrderNo>
        <BookingHeader>
            <BookingHeaderID>2</BookingHeaderID>
            <Identities>
                <Identity>
                    <IdentityId>4</IdentityId>
                    <FirstName>Roger</FirstName>
                    <LastName>Moore</LastName>
                </Identity>
                <Identity>
                    <IdentityId>5</IdentityId>
                    <FirstName>Sylvester</FirstName>
                    <LastName></LastName>
                </Identity>
                <Identity>
                    <IdentityId>6</IdentityId>
                    <FirstName>Arnold</FirstName>
                    <LastName></LastName>
                </Identity>
            </Identities>
        </BookingHeader>
        <IdentityOrders>
            <IdentityOrder>
                <IdentityId>4</IdentityId>
                <Name>Roger Moore</Name>
            </IdentityOrder>
            <IdentityOrder>
                <IdentityId>5</IdentityId>
                <Name>Sylvester</Name>
            </IdentityOrder>
        </IdentityOrders>
    </Order>
</Orders>

Wanted result after transformation改造后想要的结果

<?xml version="1.0" encoding="utf-8"?>
<Orders>
  <Order>
    <OrderNo>OR1</OrderNo>
    <Identities>
      <Identity>
        <IdentityId>1</IdentityId>
        <FirstName>John</FirstName>
        <LastName>Doe</LastName>
      </Identity>
    </Identities>
  </Order>
  <Order>
    <OrderNo>OR2</OrderNo>
    <Identities>
      <Identity>
        <IdentityId>1</IdentityId>
        <FirstName>John</FirstName>
        <LastName>Doe</LastName>
      </Identity>
      <Identity>
        <IdentityId>3</IdentityId>
        <FirstName>Betty</FirstName>
        <LastName>Blue</LastName>
      </Identity>
    </Identities>
  </Order>
  <Order>
    <OrderNo>OR3</OrderNo>
    <Identities>
      <Identity>
        <IdentityId>3</IdentityId>
        <FirstName>Betty</FirstName>
        <LastName>Blue</LastName>
      </Identity>
    </Identities>
  </Order>
  <Order>
    <OrderNo>OR4</OrderNo>
    <Identities>
      <Identity>
        <IdentityId>4</IdentityId>
        <FirstName>Roger</FirstName>
        <LastName>Moore</LastName>
      </Identity>
    </Identities>
  </Order>
</Orders>

XSLT Transformation script. XSLT 转换脚本。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/*">
        <Orders>
            <xsl:apply-templates select="Order[BookingHeader/Identities/Identity[LastName[text()]]]" />
        </Orders>
    </xsl:template>
    <xsl:template match="Order">tra
        <Order>
            <OrderNo>
                <xsl:value-of select="OrderNo" />
            </OrderNo>
            <Identities>
                <xsl:for-each select="IdentityOrders/IdentityOrder">
                    <xsl:variable name="id" select="IdentityId" />
                    <xsl:for-each select="../../BookingHeader/Identities/Identity">
                        <xsl:if test="(IdentityId=$id) and (LastName!='') ">
                            <xsl:apply-templates select="." />
                        </xsl:if>
                    </xsl:for-each>
                </xsl:for-each>
            </Identities>
        </Order>
    </xsl:template>

    <xsl:template match="Identity">
        <Identity>
            <IdentityId>
                <xsl:value-of select="IdentityId" />
            </IdentityId>
            <FirstName>
                <xsl:value-of select="FirstName" />
            </FirstName>
            <LastName>
                <xsl:value-of select="LastName" />
            </LastName>
        </Identity>
    </xsl:template>
</xsl:stylesheet>

I am guessing (:) you want to do:我猜 (:) 你想做:

XSLT 1.0 XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="id" match="Identity" use="concat(IdentityId, '|', ancestor::Order/OrderNo)" />

<xsl:template match="/Orders">
    <xsl:copy>
        <xsl:for-each select="Order">
            <xsl:variable name="id" select="key('id', concat(IdentityOrders/IdentityOrder/IdentityId, '|', OrderNo))" />
            <xsl:if test="$id/LastName/text()">
                <xsl:copy>
                    <xsl:copy-of select="OrderNo"/>
                    <Identities>
                        <xsl:copy-of select="$id"/>
                    </Identities>
                </xsl:copy>
            </xsl:if>
        </xsl:for-each> 
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

This uses a key to select the Identity whose IdentityId is listed in IdentityOrders .这使用IdentityOrders密钥,其IdentityIdentityId中列出。 Then it checks if the selected Identity has a value in its LastName and if it does, it copies the Order along with its OrderNo and the selected Identity .然后它检查所选Identity在其LastName中是否有值,如果有,则复制Order及其OrderNo和所选Identity

Note that the structure of your XML allows an Order to have more that one IdentityOrder - and it's not clear what the result should be in such case.请注意,您的 XML 的结构允许一个Order拥有多个IdentityOrder - 在这种情况下结果应该是什么尚不清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM