2017-02-13 6 views
-1

Я очень новичок в преобразовании XSLT. Я должен сделать преобразование сообщения FPML в более простой XML, который удалит атрибуты href и ID. (Моя целевая система не понимает этот тип сложного XML)Преобразование XSLT заменяет возникновение элементов href путем копирования другого элемента

Итак, часть моего ввода XML что-то вроде этого

<fpml:partyTradeInformation> 
       <fpml:partyReference href="Party1"/> 
       <fpml:accountReference href="Book1"/> 
</fpml:partyTradeInformation> 

and in same xml at bottom is the Party1 reference 
    <party id="Party1"> 
     <fpml:partyId partyIdScheme="urn:abc:party-id:EMX-LOH">What is the partyName for PQR?</fpml:partyId> 
     <fpml:partyId partyIdScheme="urn:abc:party-id:PO_ID">PO19</fpml:partyId> 
     <fpml:partyId partyIdScheme="urn:abc:party-id:PO">PO19</fpml:partyId> 
     <fpml:partyId partyIdScheme="urn:abc:party-id:TREATS_ID">MNO</fpml:partyId> 
     <fpml:partyName>What is the partyName for PQR?</fpml:partyName> 
    </party> 

Now first i have to transform my party1 to like below which I am able to do 
    <Party1> 
     <EMX-LOH>What is the partyName for ABC?</EMX-LOH> 
     <PO_ID>PO19</PO_ID><PO>PO19</PO> 
     <PO>PO19</PO> 
     <TREATS_ID>XYZ</TREATS_ID> 
     <partyName xmlns="">What is the partyName for ABC?</partyName> 
    </Party1> 

But then i have to also replace my <fpml:partyReference href="Party1"/> like 
<partyReference> 
    <party> 
     <Party1> 
      <EMX-LOH>What is the partyName for ABC?</EMX-LOH> 
      <PO_ID>PO19</PO_ID><PO>PO19</PO> 
      <PO>PO19</PO> 
      <TREATS_ID>XYZ</TREATS_ID> 
      <partyName xmlns="">What is the partyName for ABC?</partyName> 
     </Party1> 
    </party> 
</partyReference > 

Как скопировать преобразованный элемент Party1 в экземпляр href? Также, когда я пытаюсь выполнить сопоставление шаблона для Party1, который является преобразованным элементом XSLT, синтаксический анализатор не может его распознать. Но когда я сопоставляю элемент-участник (который является исходным), синтаксический анализатор может распознать его.

+0

Ваш вопрос непонятен. Пожалуйста, опубликуйте [mcve], включая XML, ваш текущий XSLT и ожидаемый результат. - Я * думаю * вы хотите узнать, как использовать [ключ] (https://www.w3.org/TR/xslt/#key). –

ответ

0

Для начала XSLT заменит участник href на соответствующий элемент партии.

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

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

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

    <xsl:template match="fpml:partyReference[@href]"> 
     <xsl:variable name="href" select="@href" /> 
     <partyReference> 
      <party> 
       <xsl:apply-templates select="//party[@id=$href]" mode="dereference" /> 
      </party> 
     </partyReference> 
    </xsl:template> 

    <xsl:template match="party" /> 

    <xsl:template match="party" mode="dereference"> 
     <xsl:element name="{@id}"> 
      <xsl:apply-templates select="node()|@*[not(local-name()='id')]" /> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

Видя, как я не знаю, что ваш fpml префикс связывается, я вставил какой-то образец URI для этого пространства имен.

Первый подходящий шаблон node()|@* - это стандартный подход, который просто скопирует все, что не соответствует никаким другим шаблонам.

Второй шаблон, соответствующий fpml:partyReference[@href], будет принимать любую сторонуReference с атрибутом href (в данном пространстве имен), извлекает значение переменной @href для переменной и затем применяет шаблоны к любому элементу партии, где атрибут id соответствует этому значению href , Обратите внимание, как он вводит режим с названием «разыменование». Это имя произвольно и что-то я выбрал.

Следующий шаблон пуст, который соответствует всем party элементам и ничего не делает. Они не будут скопированы. Это позволяет избежать повторного копирования партии после того, как она уже была помещена в ссылку ранее.

И, наконец, шаблон, который соответствует всем элементам party, но только в режиме dereference. Это создаст новый элемент с именем имени значения атрибута id, а затем применит шаблоны к атрибутам и дочерним узлам, за исключением атрибута id (так как вы не хотите, чтобы его копировали на выходе). Это будет просто по умолчанию для копирования содержимого.

Поскольку у меня недостаточно информации о том, что эти атрибуты partyIdScheme на вашем входе делают, я не преобразовал это содержимое. Вышеприведенное должно дать вам некоторые указания о том, как это решить. Обратите внимание, что вам нужно будет изменить XSLT с правильным пространством имен для префикса fpml и что вам может потребоваться изменить использование пространства имен, поскольку ваши XML-выдержки оставляют неопределенность в отношении того, что находится в пространстве имен (нам нужно будет увидеть хорошо сформированные XML-документ, чтобы понять это, а не выдержки).

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

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

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

EDIT: пример соответствия нескольких элементов в том же количестве шаблонов, что и выше. Обратите внимание, что это будет работать, только если атрибут id во входном XML уникален для каждого элемента, на который можно ссылаться href. В противном случае результаты могут быть неверными.

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

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

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

    <xsl:template match="fpml:partyReference[@href]|fpml:accountReference[@href]|fpml:payerPartyReference[@href]"> 
     <xsl:variable name="href" select="@href" /> 
     <xsl:element name="{local-name()}" namespace="{namespace-uri()}"> 
      <xsl:apply-templates select="//*[@id=$href]" mode="dereference" /> 
     </xsl:element> 
    </xsl:template> 

    <xsl:template match="party|account|payerParty" /> 

    <xsl:template match="party|account|payerParty" mode="dereference"> 
     <xsl:element name="{local-name()}" namespace="{namespace-uri()}"> 
      <xsl:element name="{@id}"> 
       <xsl:apply-templates select="node()|@*[not(local-name()='id')]" /> 
      </xsl:element> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 
+0

Отлично !! Thankuu так много. Это то, что я искал. Пространства имен не требуются в целевом xml. Итак, Думая об удалении с самого входа. – rashb

+0

@rashb Если этого достаточно, чтобы решить вопрос, пожалуйста, подумайте о том, чтобы принять его как ответ, щелкнув отметку галочки под партитурой. Это означает, что вы считаете, что это правильный ответ, который помогает другим пользователям и дает некоторую репутацию. Если лучший ответ должен быть опубликован позднее, вы все равно можете изменить тот, который вы принимаете. –

+0

@rashb Да, это, безусловно, возможно. Единственная сложная задача - узнать, что положить в часть ''. Это должен был быть правильный элемент, а не только «вечеринка». Если, однако, атрибуты href гарантированно уникальны даже для разных типов, вы можете просто использовать это: ' 'и настройте шаблон в режиме разыменования. Это можно использовать что-то вроде 'party | account | payerParty ...', чтобы убедиться, что только те, которые рассматриваются, или подстановочный знак. –

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