2016-12-30 2 views
0

Новичок на этом сайте и использование xslt, но работающий в roadblock, преобразующий SSRS 2008v2, превратил XML-файл в другой формат XSL для стороннего EDI-переноса. Я уже некоторое время искал этот сайт и других, но изо всех сил старался собрать все вместе. Я начинаю со следующих необработанных XML-данных;Несколько преобразований в xml-файл с использованием xslt 1

<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> 

Я сделал некоторые успехи, используя этот стиль листа, но я застрял на перегруппировке тега заголовка и отображения имен элементов.

<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> 

Любые советы или другие варианты были бы очень признательны!

+0

'exclude-result-prefixes' влияет только на поведение литеральных элементов результата в вашей таблице стилей, и в вашей таблице стилей отсутствуют литералы. Я подозреваю, что вы угадываете семантику атрибута от его имени, что всегда опасно. –

ответ

0

У вас уже есть шаблон, соответствующий t:Header1 в вашем XSLT, поэтому вы не должны добавлять другой соответствующий ему, так как только один может применяться. (В вашем случае, если вы добавили шаблон, соответствующий 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 я разделил заявление на два.

+0

Спасибо, Тим, отлично работает. Это действительно помогло мне. –

Смежные вопросы