【问题标题】:how to move and format element values to its subelement using XSLT/XSL如何使用 XSLT/XSL 将元素值移动和格式化到其子元素
【发布时间】:2016-12-07 05:13:51
【问题描述】:

我的应用程序收到一个文件,该文件在名为“si”的最低元素中包含多个值,我需要在名为“ssi”的子元素中分解其中的一些值,因为其他应用程序只会接受这种方式。不是所有的“si”都会在“ssi”中被打破,只有其中一些会根据内部规则被打破。此外,输入文件中以“ssi”形式出现的所有元素都必须分组在“si 999”下。

在下面的xml中,“si”代表子项,“ssi”代表子子项,“sf”代表子字段。 “sf”仅出现在输出中,它是可能的最低元素。之所以会出现这种情况,是因为某些代码实际上是一组子代码,并且输入文件没有将它们分隔到尽可能低的位置,但另一个应用程序会期望这种方式。

例如:

<c:si name="001" value="1234"/>

需要改造

<c:si name="001">
 <c:ssi name="sf1" value="12"/>
 <c:ssi name="sf2" value="34"/>
<\c:si>

同时

<c:si name="002" value="abcd"/>

不会发生任何变化,因此输出将完全相同。换句话说,有一定的内部业务规则说 si 001 实际上是两个子代码的连接,而 si 002 只是一个代码。内部输入不显示,输出必须按照下面的例子说明清楚。

并且所有输入的ssi必须移到si name="999"下

例如:

<c:ssi name="0001" value="123456"/>
<c:ssi name="0002" value="abcdef"/>

成为xml输出:

<c:si name="999">
 <c:ssi name="0001" value="123456"/>
 <c:ssi name="0002" value="abcdef"/>
</c:si>

这里是整个例子:

输入 xml

<c:product xmlns:c="myapp">
       <c:item>
              <c:si name="001" value="1234"/>
              <c:ssi name="0001" value="123456"/>
              <c:si name="002" value="abcd"/>
              <c:ssi name="0002" value="abcdef"/>
       </c:item>
       <c:item>
              <c:si name="001" value="9876"/>
              <c:ssi name="0001" value="987654"/>
              <c:si name="002" value="ghij"/>
              <c:ssi name="0002" value="lmnopq"/>
       </c:item>
</c:product>

所需的输出文件:

<c:product xmlns:c="myapp">
       <c:item>
              <c:si name="001">
                 <c:ssi name="sf1" value="12"/>
                 <c:ssi name="sf2" value="34"/>
              <\c:si>

              <c:si name="002" value="abcd"/>

              <c:si name="999">
                 <c:ssi name="0001" value="123456"/>
                 <c:ssi name="0002" value="abcdef"/>
              <\c:si>
       </c:item>
       <c:item>
              <c:si name="001">
                 <c:ssi name="sf1" value="98"/>
                 <c:ssi name="sf2" value="76"/>
              <\c:si>

              <c:si name="002" value="ghij"/>

              <c:si name="999">
                 <c:ssi name="0001" value="987654"/>
                 <c:ssi name="0002" value="lmnopq"/>
              <\c:si>
       </c:item>
</c:product>

今天,我正在通过解析输入文件并使用一些临时变量来调整输出。最近,我了解了 XSLT/XSL,并发现它在我的场景中是多么有用。如果它只是几个元素,XSL 已经非常有用了,但由于它的数量非常多,它变得更适合我的情况。当您认为我可以拥有直到 100 si 和直到 1000 ssi 时,您可以想象这是多么大的努力。

那么,如何将所有传入的 ssi 移动到 si 999 以及如何应用 XSL 来转换“sf”中的元素值?如果我可以为每个转换提供一个 XSL 文件/块,那么维护应用程序将变得更加容易。

【问题讨论】:

  • 您的问题没有得到解答吗?

标签: xml xslt transformation


【解决方案1】:

IIUC,你想做这样的事情:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:c="myapp">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="c:item">
    <xsl:copy>
        <c:si name="001">
            <xsl:apply-templates select="c:si[@name='001']"/>
        </c:si>
        <xsl:apply-templates select="c:si[not(@name='001')]"/>
        <c:si name="999">
            <xsl:apply-templates select="c:ssi"/>
        </c:si>
    </xsl:copy>
</xsl:template>

<xsl:template match="c:si[@name='001']">
    <c:ssi name="sf1" value="{substring(@value, 1, 2)}"/>
    <c:ssi name="sf2" value="{substring(@value, 3, 2)}"/>
</xsl:template>

</xsl:stylesheet>

请注意,这会创建 001 和 999 子项,无论它们是否有内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多