我的应用程序收到一个文件,其中包含名为“si”的最低元素中的几个值,我需要在名为“ssi”的子元素中打破其中一些值,因为其他应用程序将只接受这种方式。并不是所有的“si”都会在“ssi”中被打破,只有一些根据内部规则。此外,输入文件中作为“ssi”出现的所有元素必须分组在“si 999”下。
在下面的xml中,“si”代表subitem,“ssi”代表sub-subitem,“sf”代表subfield。 “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以及如何应用在“sf”中转换元素值的XSL?如果我可以为每次转换创建一个XSL文件/块,那么保存应用程序会更容易。
答案 0 :(得分:0)
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子项,无论它们是否包含内容。