-1

我对 XSLT 转换非常陌生。我必须将 FPML 消息转换为更简单的 XML,这将删除 href 和 ID 类型的属性。(我的目标系统不理解这种类型的复杂 XML)

所以我的输入 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 >

如何在 href 实例中复制转换后的 Party1 元素集?此外,当我尝试对作为 XSLT 转换元素的 Party1 进行模板匹配时,解析器无法识别它。但是当我匹配元素方(这是原始方)时,解析器能够识别它。

4

1 回答 1

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]将采用任何带有 href 属性的 partyReference(在给定的命名空间中),将 @href 的值提取到变量中,然后将模板应用于 id 属性与该 href 值匹配的任何派对元素。注意它是如何引入一个名为“dereference”的模式的。这个名字是任意的,是我选择的。

接下来是一个空模板,它匹配所有party元素并且什么都不做。他们不会被复制。这避免了在之前已经放置在参考中之后再次复制派对。

finally 是一个匹配所有party元素的模板,但仅限于 mode dereference。这将创建一个名称为属性值的新元素,id然后将模板应用于属性和子节点,但 id 属性除外(因为您不希望将其复制到输出中)。这将默认为复制内容。

由于我没有足够的信息来说明partyIdScheme您输入中的这些属性的作用,因此我没有转换这些内容。以上应该给你一些关于如何解决这个问题的指示。请注意,您将需要使用正确的前缀来更改 XSLT fpml,并且您可能需要更改名称空间的使用,因为您的 XML 提取在哪个名称空间中留下了一些歧义(我们需要查看格式正确的 XML文件来弄清楚这一点,而不是提取)。

此外,当我尝试对作为 XSLT 转换元素的 Party1 进行模板匹配时,解析器无法识别它。但是当我匹配元素方(这是原始方)时,解析器能够识别它。

那是因为 XSLT 仅适用于输入文档。它遍历输入,将其部分与模板匹配并执行这些模板中的指令。它是一种声明性语言。所以生成的输出不是输入的一部分,也不会影响它。为此,您需要多个 XSLT 转换。

您提供的 XML 可能使用了某些技术,例如 XInclude 或其他引用方案。您可以使用支持正确技术的解析器或实现此类引用方案的某些库来获得所需的结果,因此在您继续使用 XSLT 之前,请查看是否有某些东西已经在做您正在尝试的事情。

编辑:在与上述相同数量的模板中匹配多个元素的示例。请注意,只有当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>
于 2017-02-13T15:09:08.030 回答