-1

请帮助 XSLT,我有这个 XML 示例

<?xml version="1.0" encoding="utf-8"?>
<Document>
  <TopLevel>
    <Header>
      <!-- Header Information-->
    </Header>
    <!--Payments is a one to many-->
    <Payments>
      <PaymentID>PID1</PaymentID>
      <!--More Info-->
      <!--Transactrion can be one to many for each payment-->
      <Transaction>
        <TranssID>TR1 - PID1</TranssID>
        <TranssID>TR2 - PID1</TranssID>
        <!--More Info-->
      </Transaction>
    </Payments>
    <Payments>
      <PaymentID>PID2</PaymentID>
      <!--More Info-->
      <!--Transactrion can be one to many for each payment-->
      <Transaction>
        <TranssID>TR1 - PID2</TranssID>
        <TranssID>TR2 - PID2</TranssID>
        <!--More Info-->
      </Transaction>
    </Payments>
  </TopLevel>
</Document>

我需要 XSLT 中的循环机制,它将为我提供每次付款的交易。

这是我尝试使用模板方法 OUTPUT 时的输出:

<?xml version="1.0" encoding="utf-8"?>
<TopLevel>
  <Payments>
    <PaymentID>PID1</PaymentID>
    <transIDs>TR1 - PID1</transIDs>
    <transIDs>TR2 - PID1</transIDs>
    <transIDs>TR1 - PID2</transIDs>
    <transIDs>TR2 - PID2</transIDs>
    <transIDs>TR1 - PID1</transIDs>
    <transIDs>TR2 - PID1</transIDs>
    <transIDs>TR1 - PID2</transIDs>
    <transIDs>TR2 - PID2</transIDs>
  </Payments>
  <Payments>
    <PaymentID>PID1</PaymentID>
    <transIDs>TR1 - PID1</transIDs>
    <transIDs>TR2 - PID1</transIDs>
    <transIDs>TR1 - PID2</transIDs>
    <transIDs>TR2 - PID2</transIDs>
    <transIDs>TR1 - PID1</transIDs>
    <transIDs>TR2 - PID1</transIDs>
    <transIDs>TR1 - PID2</transIDs>
    <transIDs>TR2 - PID2</transIDs>
  </Payments>
</TopLevel>

我希望它按交易和付款分开

这是我的 XSLT

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

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <TopLevel>
      <xsl:apply-templates select="//TopLevel/Payments"/>
    </TopLevel>
  </xsl:template>

  <xsl:template match="//TopLevel/Payments">
    <Payments>
      <PaymentID>
        <xsl:value-of select="//TopLevel/Payments/PaymentID"/>
      </PaymentID>
      <xsl:apply-templates select="//TopLevel/Payments/Transaction"/>
    </Payments>
  </xsl:template>

  <xsl:template match="//TopLevel/Payments/Transaction">
    <xsl:apply-templates select="//TopLevel/Payments/Transaction/TranssID"/>
  </xsl:template>

  <xsl:template match="//TopLevel/Payments/Transaction/TranssID">
    <transIDs>
      <xsl:value-of select="."/>
    </transIDs>
  </xsl:template>

</xsl:stylesheet>
4

2 回答 2

1

您的问题是您在和说明中使用绝对路径(带有前导/)的方式。例如apply-templatesvalue-of

<xsl:apply-templates select="//TopLevel/Payments/Transaction"/>

将模板应用于整个文档中所有元素中的所有 Transaction元素 Payments这就是为什么你每次都看到的原因TranssID。您应该使用相对路径,以便仅从当前正在使用的元素中提取子元素,并且//出于效率原因,除非确实有必要,否则您应该避免使用:

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

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <TopLevel>
      <xsl:apply-templates select="Document/TopLevel/Payments"/>
    </TopLevel>
  </xsl:template>

  <xsl:template match="Payments">
    <Payments>
      <PaymentID>
        <xsl:value-of select="PaymentID"/>
      </PaymentID>
      <xsl:apply-templates select="Transaction"/>
    </Payments>
  </xsl:template>

  <xsl:template match="Transaction">
    <xsl:apply-templates select="TranssID"/>
  </xsl:template>

  <xsl:template match="TranssID">
    <transIDs>
      <xsl:value-of select="."/>
    </transIDs>
  </xsl:template>

</xsl:stylesheet>

另请注意,模板match表达式不需要返回根的完整路径,它们只需要足够的细节来消除模板之间的歧义。在您的情况下,您正在处理的所有不同元素都有不同的名称,因此单个元素名称足以匹配。

于 2013-08-27T10:36:26.550 回答
0

你有没有尝试过什么?在您使用之前,<xsl:for-each>您应该先进行<xsl:apply-templates>构造(另请参阅:For loops vs. apply-templates)。

如果应用此 XSLT:

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

<xsl:output method="xml" indent="yes"/>

<xsl:template match="/">
    <list>
        <xsl:apply-templates select="//Payments"/>
    </list>
</xsl:template>

<xsl:template match="Payments">
        <xsl:apply-templates select="Transaction"/>
</xsl:template>

<xsl:template match="Transaction">
    <xsl:apply-templates select="TranssID"/>
</xsl:template>

<xsl:template match="TranssID">
    <transIDs>
        <xsl:value-of select="."/>
    </transIDs>
</xsl:template>

</xsl:stylesheet>

到你的源 XML 你得到这个输出:

<?xml version="1.0" encoding="UTF-8"?>
<list>
 <transIDs>TR1 - PID1</transIDs>
 <transIDs>TR2 - PID1</transIDs>
 <transIDs>TR1 - PID2</transIDs>
 <transIDs>TR2 - PID2</transIDs>
</list>
于 2013-08-27T08:54:20.313 回答