使用xslt 1对xml文件进行多次转换

时间:2016-12-30 06:22:42

标签: xslt

此网站的新手并使用xslt但遇到了路障,将SSRS 2008v2呈现的xml文件转换为另一种XSL原始格式以进行第三方EDI传输。我一直在搜索这个网站和其他网站一段时间了,但我们正在努力将它们放在一起。我从以下原始xml数据开始;

<Invoices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns="http://www.spscommerce.com/RSX"  xsi:schemaLocation="http://www.spscommerce.com/RSX http://tfl- sql01/ReportServer_SQL2012? %2FTesting%2FINTest&rs%3ACommand=Render&rs%3AFormat=XML&rs%3ASessionID= jn5ugdirg4m02nmodnm0hynq&rc%3ASchema=True" Name="INTest">
<Invoices1>  ***need to remove***
  <ivhID_Collection>   ***need to remove***
  <Invoices>...</Invoices>
  <Invoices>...</Invoices>
    <Invoices>
      <Invoice>
        <Header1>
          <InvoiceHeader>...</InvoiceHeader>
          <PaymentTerms>...</PaymentTerms>
          <Dates>...</Dates>
          <Address>...</Address>
          <References>...</References>
          <ChargesAllowances>...</ChargesAllowances>
          <LineItem_Collection>   ***need to remove and replace with </Header>***
            <LineItem>
              <InvoiceLine>...</InvoiceLine>
              <ProductOrItemDescription>...</ProductOrItemDescription>
            </LineItem>
            <LineItem>
              <InvoiceLine>...</InvoiceLine>
              <ProductOrItemDescription>...</ProductOrItemDescription>
            </LineItem>
          </LineItem_Collection>   ***need to remove***
          <Summary>...</Summary>
        </Header1>   ***need to remove***
      </Invoice>
    </Invoices>
    <Invoices>...</Invoices>
    <Invoices>...</Invoices>
    <Invoices>...</Invoices>
  /ivhID_Collection>   ***need to remove***
 </Invoices1>   ***need to remove***
</Invoices>

尝试在此结构中获取它;

<Invoices xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.spscommerce.com/RSX" xsi:schemaLocation="http://www.spscommerce.com/RSX http://tfl-sql01/ReportServer_SQL2012?%2FTesting%2FINDoItBest%20v7&rs%3ACommand=Render&rs%3AFormat=XML&rs%3ASessionID=jn5ugdirg4m02nmodnm0hynq&rc%3ASchema=True" Name="INDoItBest v7">
<Invoices>...</Invoices>
<Invoices>...</Invoices>
  <Invoices>
    <Invoice>
      <Header>
        <InvoiceHeader>...</InvoiceHeader>
        <PaymentTerms>...</PaymentTerms>
        <Dates>...</Dates>
        <Address>...</Address>
        <References>...</References>
        <ChargesAllowances>...</ChargesAllowances>
      </Header>
      <LineItem>
        <InvoiceLine>...</InvoiceLine>
        <ProductOrItemDescription>...</ProductOrItemDescription>
      </LineItem>
      <LineItem>
        <InvoiceLine>...</InvoiceLine>
        <ProductOrItemDescription>...</ProductOrItemDescription>
      </LineItem>
      <Summary>...</Summary>
    </Invoice>
  </Invoices>
  <Invoices>...</Invoices>
  <Invoices>...</Invoices>
  <Invoices>...</Invoices>
</Invoices>

我使用此样式表取得了一些进展,但我仍然坚持重新组合Header标记和元素名称空间的显示。

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

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

<!--rule to suppress the undesired nodes-->
<xsl:template match="t:Invoices1|t:ivhID_Collection">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="t:LineItem_Collection">
  <xsl:apply-templates/>
</xsl:template>

<!--<xsl:template match="t:Invoice/t:Header1">
  <xsl:apply-templates/>
</xsl:template>-->

<!-- Identity Transform --> 
<xsl:template match="t:Header1">
  <xsl:copy>
    <xsl:element name="Header">
      <xsl:apply-templates   select="@*|t:InvoiceHeader|t:PaymentTerms|t:Dates|t:Address|t:References|t:ChargesAllowances"/>
    </xsl:element>
    <xsl:apply-templates select="@*|t:LineItem_Collection|t:Summary"/>
  </xsl:copy>
</xsl:template>

<!-- Had to comment out --> 
<!--<xsl:template match="t:Invoice/t:Header1">
  <xsl:apply-templates/>
</xsl:template>-->

样式表生成了我需要的大部分内容,但是当我尝试删除Header1标记(代码注释掉)时失败了。此外,努力理解为什么“exclude-result-prefixes”无法从新的xml文件中删除命名空间。

<Invoices xmlns="http://www.spscommerce.com/RSX" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.spscommerce.com/RSX http://tfl-sql01/ReportServer_SQL2012?%2FTesting%2FINDoItBest%20v7&rs%3ACommand=Render&rs%3AFormat=XML&rs%3ASessionID=jn5ugdirg4m02nmodnm0hynq&rc%3ASchema=True" Name="INDoItBest v7">
<Invoices>...</Invoices>
<Invoices>...</Invoices>
<Invoices>
  <Invoice>
    <Header1>
      <Header xmlns="">
        <InvoiceHeader xmlns="http://www.spscommerce.com/RSX">...   </InvoiceHeader>
        <PaymentTerms xmlns="http://www.spscommerce.com/RSX">...   </PaymentTerms>
        <Dates xmlns="http://www.spscommerce.com/RSX">...</Dates>
        <Address xmlns="http://www.spscommerce.com/RSX">...</Address>
        <References xmlns="http://www.spscommerce.com/RSX">...</References>
        <ChargesAllowances xmlns="http://www.spscommerce.com/RSX">...  </ChargesAllowances>
      </Header>
      <LineItem>
        <InvoiceLine>...</InvoiceLine>
        <ProductOrItemDescription>...</ProductOrItemDescription>
      </LineItem>
      <LineItem>
        <InvoiceLine>...</InvoiceLine>
        <ProductOrItemDescription>...</ProductOrItemDescription>
      </LineItem>
      <Summary>
        <TotalAmount>756.8400</TotalAmount>
        <TotalSalesAmount>727.1600</TotalSalesAmount>
        <TotalLineItemNumber>2</TotalLineItemNumber>
      </Summary>
    </Header1>
  </Invoice>
</Invoices>
<Invoices>...</Invoices>
<Invoices>...</Invoices>
<Invoices>...</Invoices>
</Invoices>

非常感谢任何建议或其他选择!

1 个答案:

答案 0 :(得分:0)

您的XSLT中已经有一个匹配t:Header1的模板,因此您不应添加另一个与之匹配的模板,因为只有一个可以应用。 (在您的情况下,如果您确实添加了匹配t:Invoice\t:Header1的模板,那么由于指定了父级,它将具有更高的优先级,因为它只匹配t:Header1并且可以替代使用)。

您需要做的是将所有逻辑放在单个模板中。在这种情况下,您需要做的就是从该模板中删除xsl:copy以避免将Header1复制到输出树。此外,在创建Header时,您将在无命名空间中创建它,而不是在绑定到前缀“t”的命名空间中创建它。因此,子元素将被赋予新的命名空间声明,因为它们仍将位于该命名空间中。

一种方法是简单地向xsl:element添加“名称空间”属性,如下所示:

<xsl:element name="Header" namespace="http://www.spscommerce.com/RSX">

或者,您可以通过执行<Header>来创建元素,但是您还需要向XSLT添加默认命名空间声明,以确保它在正确的命名空间中输出。

试试这个XSLT:

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

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

<!--rule to suppress the undesired nodes-->
<xsl:template match="t:Invoices1|t:ivhID_Collection">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="t:LineItem_Collection">
  <xsl:apply-templates/>
</xsl:template>

<!-- Identity Transform --> 
<xsl:template match="t:Header1">
    <xsl:apply-templates select="@*" />
    <Header>
      <xsl:apply-templates select="@*|t:InvoiceHeader|t:PaymentTerms|t:Dates|t:Address|t:References|t:ChargesAllowances"/>
    </Header>
    <xsl:apply-templates select="t:LineItem_Collection|t:Summary"/>
</xsl:template>
</xsl:stylesheet>

作为旁注,在您的XSLT中,您在创建Header元素后立即执行此操作

<xsl:apply-templates select="@*|t:LineItem_Collection|t:Summary"/>

如果Header1具有您要复制的属性,则会失败,因为在创建子元素后尝试向父元素添加属性是错误的。这就是为什么在我的XSLT中我将语句拆分为两个。