2013-02-21 2 views
0

Как видно, мои знания XML и XSLT довольно ограничены. Пожалуйста, кто-нибудь может помочь мне с файлом перевода, который позволит передать каждый ItemNumber/Заказ на продажу в следующем XML, чтобы второй XML был создан для каждого элемента. Другими словами, мне нужно создать несколько выходных xmls (по одному для каждого заказа клиента). На данный момент я получаю только один выходной файл xml для последней позиции/заказа клиента на начальном xml.Зацикливание файла перевода для каждой строки xml

Вот XML, что мне нужно перевести:

<?xml version="1.0" encoding="Windows-1252"?> 
<postsalesorderssct Language='05' Language2='EN' CssStyle='' DecFormat='1' DateFormat='01' Role='01' Version='6.1.009' OperatorPrimaryRole=' '> 
    <Item> 
     <Key> 
      <SalesOrder>197588</SalesOrder> 
      <SourceWarehouse>A3</SourceWarehouse> 
      <TargetWarehouse>PV</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000001</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197589</SalesOrder> 
      <SourceWarehouse>A3</SourceWarehouse> 
      <TargetWarehouse>HI</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000002</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197590</SalesOrder> 
      <SourceWarehouse>A3</SourceWarehouse> 
      <TargetWarehouse>WS</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000003</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197591</SalesOrder> 
      <SourceWarehouse>A4</SourceWarehouse> 
      <TargetWarehouse>HI</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000004</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197592</SalesOrder> 
      <SourceWarehouse>A4</SourceWarehouse> 
      <TargetWarehouse>PV</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000005</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197593</SalesOrder> 
      <SourceWarehouse>A4</SourceWarehouse> 
      <TargetWarehouse>WS</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000006</ItemNumber> 
    </Item> 
    <StatusOfItems> 
     <ItemsProcessed>000006</ItemsProcessed> 
     <ItemsInvalid>000000</ItemsInvalid> 
    </StatusOfItems> 
</postsalesorderssct> 

Вот файл перевода я в настоящее время с помощью:

<?xml version="1.0" ?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output method="xml" encoding="Windows-1252" omit-xml-declaration="yes" /> 
<xsl:template match="/"> 
<Query> 
<Key> 
    <xsl:for-each select = "postsalesorderssct/Item/Key"> 
     <SalesOrder><xsl:value-of select="SalesOrder"/></SalesOrder> 
    </xsl:for-each> 
</Key> 
</Query> 
</xsl:template> 
</xsl:stylesheet> 

Здесь требуемая мощность для каждого из ItemNumbers на начальный xml. Другими словами, мне нужен один из них для каждого номера заказа клиента:

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORQRY.XSD"> 
    <Key> 
     <SalesOrder>197588</SalesOrder> 
     <Invoice/> 
    </Key> 
    <Option> 
     <IncludeStockedLines>Y</IncludeStockedLines> 
     <IncludeNonStockedLines>Y</IncludeNonStockedLines> 
     <IncludeFreightLines>Y</IncludeFreightLines> 
     <IncludeMiscLines>Y</IncludeMiscLines> 
     <IncludeCommentLines>Y</IncludeCommentLines> 
     <IncludeCompletedLines>Y</IncludeCompletedLines> 
     <IncludeSerials>N</IncludeSerials> 
     <IncludeLots>Y</IncludeLots> 
     <IncludeBins>Y</IncludeBins> 
     <IncludeAttachedItems>N</IncludeAttachedItems> 
     <IncludeCustomForms>Y</IncludeCustomForms> 
     <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms> 
     <XslStylesheet/> 
    </Option> 
</Query> 

Благодарим вас в ожидании.

+0

Ваш XSLT не соответствует вашему входному XML. Например, в вашем XSLT вы используете 'postsororderstatus/Item/Order', но во входном XML корневой каталог' ', поэтому не существует. Также вы просматриваете каждый '', но этот элемент также не входит в ваш входной XML. Когда я смотрю на желаемый результат, это тоже не соответствует. Так что вы хотите? Или, пожалуйста, исправьте свой вопрос! –

+0

Какую версию XSLT вы используете? В XSLT 1.0 теперь можно сделать это без использования элементов расширения (если у вас есть доступ к exslt, вы можете использовать ). В XSLT 2.0 вы можете использовать для создания нескольких выходных файлов. –

+0

Мои извинения. У меня было открытое несколько файлов и скопировано неправильное. Я отрегулирую вопрос соответствующим образом. –

ответ

1

Если вы можете использовать XSLT 2.0, должно работать ...

XML Input

<postsalesorderssct Language='05' Language2='EN' CssStyle='' DecFormat='1' DateFormat='01' Role='01' Version='6.1.009' OperatorPrimaryRole=' '> 
    <Item> 
     <Key> 
      <SalesOrder>197588</SalesOrder> 
      <SourceWarehouse>A3</SourceWarehouse> 
      <TargetWarehouse>PV</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000001</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197589</SalesOrder> 
      <SourceWarehouse>A3</SourceWarehouse> 
      <TargetWarehouse>HI</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000002</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197590</SalesOrder> 
      <SourceWarehouse>A3</SourceWarehouse> 
      <TargetWarehouse>WS</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000003</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197591</SalesOrder> 
      <SourceWarehouse>A4</SourceWarehouse> 
      <TargetWarehouse>HI</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000004</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197592</SalesOrder> 
      <SourceWarehouse>A4</SourceWarehouse> 
      <TargetWarehouse>PV</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000005</ItemNumber> 
    </Item> 
    <Item> 
     <Key> 
      <SalesOrder>197593</SalesOrder> 
      <SourceWarehouse>A4</SourceWarehouse> 
      <TargetWarehouse>WS</TargetWarehouse> 
      <CustomerPoNumber/> 
     </Key> 
     <ItemNumber>000006</ItemNumber> 
    </Item> 
    <StatusOfItems> 
     <ItemsProcessed>000006</ItemsProcessed> 
     <ItemsInvalid>000000</ItemsInvalid> 
    </StatusOfItems> 
</postsalesorderssct> 

XSLT 2,0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/postsalesorderssct/Item"> 
     <xsl:result-document href="{Key/SalesOrder}.xml"> 
      <Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORQRY.XSD"> 
       <Key> 
        <xsl:copy-of select="Key/SalesOrder"/> 
        <Invoice/> 
       </Key> 
       <Option> 
        <IncludeStockedLines>Y</IncludeStockedLines> 
        <IncludeNonStockedLines>Y</IncludeNonStockedLines> 
        <IncludeFreightLines>Y</IncludeFreightLines> 
        <IncludeMiscLines>Y</IncludeMiscLines> 
        <IncludeCommentLines>Y</IncludeCommentLines> 
        <IncludeCompletedLines>Y</IncludeCompletedLines> 
        <IncludeSerials>N</IncludeSerials> 
        <IncludeLots>Y</IncludeLots> 
        <IncludeBins>Y</IncludeBins> 
        <IncludeAttachedItems>N</IncludeAttachedItems> 
        <IncludeCustomForms>Y</IncludeCustomForms> 
        <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms> 
        <XslStylesheet/> 
       </Option> 
      </Query>   
     </xsl:result-document>  
    </xsl:template> 

</xsl:stylesheet> 

Это даст вам индивидуальный файл для каждого Item. Имя файла будет SalesOrder.

Несколько примеров ...

197588.xml

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" 
     xsd:noNamespaceSchemaLocation="SORQRY.XSD"> 
    <Key> 
     <SalesOrder>197588</SalesOrder> 
     <Invoice/> 
    </Key> 
    <Option> 
     <IncludeStockedLines>Y</IncludeStockedLines> 
     <IncludeNonStockedLines>Y</IncludeNonStockedLines> 
     <IncludeFreightLines>Y</IncludeFreightLines> 
     <IncludeMiscLines>Y</IncludeMiscLines> 
     <IncludeCommentLines>Y</IncludeCommentLines> 
     <IncludeCompletedLines>Y</IncludeCompletedLines> 
     <IncludeSerials>N</IncludeSerials> 
     <IncludeLots>Y</IncludeLots> 
     <IncludeBins>Y</IncludeBins> 
     <IncludeAttachedItems>N</IncludeAttachedItems> 
     <IncludeCustomForms>Y</IncludeCustomForms> 
     <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms> 
     <XslStylesheet/> 
    </Option> 
</Query> 

197592.xml

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" 
     xsd:noNamespaceSchemaLocation="SORQRY.XSD"> 
    <Key> 
     <SalesOrder>197592</SalesOrder> 
     <Invoice/> 
    </Key> 
    <Option> 
     <IncludeStockedLines>Y</IncludeStockedLines> 
     <IncludeNonStockedLines>Y</IncludeNonStockedLines> 
     <IncludeFreightLines>Y</IncludeFreightLines> 
     <IncludeMiscLines>Y</IncludeMiscLines> 
     <IncludeCommentLines>Y</IncludeCommentLines> 
     <IncludeCompletedLines>Y</IncludeCompletedLines> 
     <IncludeSerials>N</IncludeSerials> 
     <IncludeLots>Y</IncludeLots> 
     <IncludeBins>Y</IncludeBins> 
     <IncludeAttachedItems>N</IncludeAttachedItems> 
     <IncludeCustomForms>Y</IncludeCustomForms> 
     <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms> 
     <XslStylesheet/> 
    </Option> 
</Query> 
+0

Привет, Даниэль. К сожалению, я не могу использовать xslt 2.0. Любая идея, как достичь этого, используя версию 1, пожалуйста? –

+0

@DevonTrew - Если ваш процессор поддерживает exslt, вы можете использовать 'exsl: document'. См. Http://www.exslt.org/exsl/elements/document/index.html –

1

Достижение этой цели с помощью XSLT 2.0 довольно прост, как и Даниил продемонстрировал. К сожалению, с чистым XSLT 1.0 это невозможно, насколько я могу судить, но вы можете добиться того же результата, если захотите работать немного сложнее.

(я бы не назвал это элегантным решением любых средств, но это первый метод, который я могу придумать для решения этой проблемы без XSLT 2.0.)

Я не знаю, какой XSLT процессор вам я использую, поэтому я продемонстрирую с помощью xsltproc.

Вы можете первым использовать таблицу стилей, как это создать файл XML, содержащий все <Query> элементы (назовем его с xsltproc allQuery.xsl input.xml):

<!-- allQuery.xsl --> 

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
     xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"> 
     <xsl:output method="xml" encoding="Windows-1252" omit-xml-declaration="yes" indent="yes"/> 

     <xsl:template match="/"> 
     <Queries> 
      <xsl:apply-templates select="postsalesorderssct/Item/Key/SalesOrder"/> 
     </Queries> 
     </xsl:template> 

     <xsl:template match="SalesOrder"> 
     <xsl:variable name="id" select="."/> 
      <Query xsd:noNamespaceSchemaLocation="SORQRY.XSD"> 
      <Key> 
       <xsl:copy> 
       <xsl:apply-templates/> 
       </xsl:copy> 
       <Invoice/> 
      </Key> 
      <Option> 
       <IncludeStockedLines>Y</IncludeStockedLines> 
       <IncludeNonStockedLines>Y</IncludeNonStockedLines> 
       <IncludeFreightLines>Y</IncludeFreightLines> 
       <IncludeMiscLines>Y</IncludeMiscLines> 
       <IncludeCommentLines>Y</IncludeCommentLines> 
       <IncludeCompletedLines>Y</IncludeCompletedLines> 
       <IncludeSerials>N</IncludeSerials> 
       <IncludeLots>Y</IncludeLots> 
       <IncludeBins>Y</IncludeBins> 
       <IncludeAttachedItems>N</IncludeAttachedItems> 
       <IncludeCustomForms>Y</IncludeCustomForms> 
       <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms> 
       <XslStylesheet/> 
      </Option> 
      </Query> 
     </xsl:template> 
    </xsl:stylesheet> 

Тогда вы могли бы иметь другую простую таблицу стилей, как это:

<!-- extractQuery.xsl --> 

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"> 

    <xsl:output method="xml" encoding="Windows-1252" omit-xml-declaration="yes" indent="yes"/> 

    <!-- The sales order number you pass in on the command line. --> 
    <xsl:param name="salesOrderNo"/> 

    <xsl:template match="/"> 
    <!-- 
    Only apply the <Query> element with a <SalesOrder> descendant that has 
    $salesOrderNo as its text content -- in the case of this example, 197593. 
    --> 
    <xsl:apply-templates select="Queries/Query[descendant::SalesOrder[. = $salesOrderNo]]"/> 
    </xsl:template> 

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

</xsl:stylesheet> 

Вы можете использовать эту таблицу стилей с xsltproc вот так, переходя в номер SalesOrder элемента <Query>, который вы хотите получить в качестве параметра в таблице стилей:

xsltproc --stringparam salesOrderNo 197593 extractQuery.xsl output.xml 

Это произведет следующий вывод:

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORQRY.XSD"> 
    <Key> 
    <SalesOrder>197593</SalesOrder> 
    <Invoice/> 
    </Key> 
    <Option> 
    <IncludeStockedLines>Y</IncludeStockedLines> 
    <IncludeNonStockedLines>Y</IncludeNonStockedLines> 
    <IncludeFreightLines>Y</IncludeFreightLines> 
    <IncludeMiscLines>Y</IncludeMiscLines> 
    <IncludeCommentLines>Y</IncludeCommentLines> 
    <IncludeCompletedLines>Y</IncludeCompletedLines> 
    <IncludeSerials>N</IncludeSerials> 
    <IncludeLots>Y</IncludeLots> 
    <IncludeBins>Y</IncludeBins> 
    <IncludeAttachedItems>N</IncludeAttachedItems> 
    <IncludeCustomForms>Y</IncludeCustomForms> 
    <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms> 
    <XslStylesheet/> 
    </Option> 
</Query> 

Вы бы тогда нужно вызвать xsltproc один раз для каждого номера заказа клиента вы хотите создать файл XML для. Один из способов сделать это, чтобы создать еще другой таблицы стилей XSLT:

<!-- getSalesOrderNos.xsl --> 

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"> 

    <xsl:output method="text" encoding="Windows-1252" omit-xml-declaration="yes"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates select="Queries/Query/Key/SalesOrder"/> 
    </xsl:template> 

    <xsl:template match="SalesOrder"> 
    <xsl:value-of select="."/><xsl:text> 
</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

Это выведет из новой строки разделенного списка всех номеров заказов на продажу. После этого вы можете использовать его с Bash сценарий, как это:

xsltproc getSalesOrderNos.xsl output.xml | xargs -L1 -I no xsltproc \ 
-o SalesOrder-no.xml --stringparam salesOrderNo no extractQuery.xsl output.xml 

По сути, это будет распечатать список всех номеров заказов на продажу в output.xml и запустить extractQuery.xsl один раз для каждого номера - с номером прошло в в качестве параметра extractQuery.xsl - и создайте новый файл (называемый SalesOrder-<ordernumber>.xml) для результата каждого преобразования. Как и в случае:

<!-- SalesOrder-197588.xml --> 

<Query xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance" xsd:noNamespaceSchemaLocation="SORQRY.XSD"> 
    <Key> 
    <SalesOrder>197588</SalesOrder> 
    <Invoice/> 
    </Key> 
    <Option> 
    <IncludeStockedLines>Y</IncludeStockedLines> 
    <IncludeNonStockedLines>Y</IncludeNonStockedLines> 
    <IncludeFreightLines>Y</IncludeFreightLines> 
    <IncludeMiscLines>Y</IncludeMiscLines> 
    <IncludeCommentLines>Y</IncludeCommentLines> 
    <IncludeCompletedLines>Y</IncludeCompletedLines> 
    <IncludeSerials>N</IncludeSerials> 
    <IncludeLots>Y</IncludeLots> 
    <IncludeBins>Y</IncludeBins> 
    <IncludeAttachedItems>N</IncludeAttachedItems> 
    <IncludeCustomForms>Y</IncludeCustomForms> 
    <IncludeDetailLineCustomForms>Y</IncludeDetailLineCustomForms> 
    <XslStylesheet/> 
    </Option> 
</Query> 

Как я уже сказал, это не очень мило. В зависимости от того, к каким инструментам вы имеете доступ, вы можете немного упростить этот процесс (например, использовать что-то еще, кроме XSLT, для извлечения списка номеров заказа клиента и перехода оттуда).

+0

+1 для жизнеспособного решения, если XSLT 2.0 или EXSL недоступны. –

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