我遇到的情况似乎超出了我在XSLT中的技能。问题如下:我有两个输入文件tuplelist.xml和orderlist.xml。前者包含一些应该添加到第二个文件的信息(我在其上运行我的.xsl文件)。 文件如下所示:
编辑:文件现在包含应添加距离的实际样本。 在添加下面答案中建议的更改后,输出基本上包含了我的orderlist.xml的复制品,但没有添加距离元素。
tuplelist.xml
<TU:tuplelist xmlns:TU="www.tuplelist.com">
<tuple xmlns="http://ws.apache.org/ns/synapse">
<start>Regensburg, Germany</Start>
<destination>Bremerhaven, Germany</destination>
<distance>736 km</distance>
</tuple>
<!-- more <tuple> Elements here -->
</tuplelist>
orderlist.xml
<orderlist xmlns="http://ws.apache.org/ns/synapse">
<order>
<nr>Transportauftrag</nr>
<sender>
<name>somename</name>
<street>somestreet</street>
<number>somenumber</number>
<zip>somezip</zip>
<town>Regensburg</town>
<country>Germany</country>
</sender>
<recipient>
<name>aname</name>
<street>astreet</street>
<number>anumber</number>
<zip>azip</zip>
<town>Bremerhaven</town>
<country>Germany</country>
</recipient>
</order>
<!-- more <order> elements here -->
</orderlist>
现在我要做的是为每个添加拟合元素。我想要做的是将每个发送者/城镇和每个发送者/城镇与每个接收者/城镇进行比较,正如我在当前的xslt中可以看到的那样:
merge.xlst
<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:OL="http://ws.apache.org/ns/synapse" xmlns:TL="www.tuplelist.com" xmlns:T="http://ws.apache.org/ns/synapse">
<xsl:variable name="TL" select="document('C:/Users/admin/Desktop/tuplelist.xml')" />
<xsl:template match="OL:orderlist">
<orderlist>
<xsl:for-each select="./OL:order">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
<xsl:variable name="sta" select="./OL:sender/OL:town/text()"/>
<xsl:variable name="dest" select="./OL:recipient/OL:town/text()"/>
<xsl:for-each select="document($TL)/TL:tuplelist/T:tuple">
<xsl:if test="starts-with(./OL:start, sta)">
<xsl:if test="starts-with(./OL:destination, dest)">
<distance>
<xsl:apply-templates select="./T:distance/text()"/>
</distance>
</xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</orderlist>
</xsl:template>
</xsl:stylesheet>
我认为我的命名空间是正确的,似乎无法找到我做错的事情,请你帮忙解决一下? 注意:我在WSO2 ESB中运行它并且实际上看不到我的xslt的输出,因为它只打印出错误。
答案 0 :(得分:1)
我想你只想要
<xsl:variable name="sta" select="OL:sender/OL:town"/>
<xsl:variable name="dest" select="OL:recipient/OL:town"/>
<xsl:copy-of select="$TL/TL:tuplelist/T:tuple[starts-with(OL:start, $sta) and starts-with(OL:destination, $dest)]/T:distance">
而不是
<xsl:variable name="sta" select="./OL:sender/OL:town/text()"/>
<xsl:variable name="dest" select="./OL:recipient/OL:town/text()"/>
<xsl:for-each select="document($TL)/TL:tuplelist/T:tuple">
<xsl:if test="starts-with(./OL:start, sta)">
<xsl:if test="starts-with(./OL:destination, dest)">
<distance>
<xsl:apply-templates select="./T:distance/text()"/>
</distance>
</xsl:if>
</xsl:if>
</xsl:for-each>
使用<xsl:variable name="TL" select="document('file:///C:/Users/admin/Desktop/tuplelist.xml')" />
代替<xsl:variable name="TL" select="document('C:/Users/admin/Desktop/tuplelist.xml')" />
可能更安全甚至是必要的。
此外,如果您想使用
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
然后你需要添加一个模板,确保子节点处理<xsl:apply-templates/>
进程,通常的方法是包含身份转换模板
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
在样式表中。
作为替代方案,您只需复制子节点即可。
<xsl:copy>
<xsl:copy-of select="node()"/>
</xsl:copy>
你可能想把代码找到匹配的距离在xsl:copy
之内,而不是在它之下。
最后,输入XML具有名称空间xmlns:TU="www.tuplelist.com"
,而您的XSLT声明xmlns:TL="www.tupelliste.com"
,您需要确保具有相同的网址xmlns:TL="www.tuplelist.com"
。
所有这些更正我已到达
<xsl:stylesheet version = '1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:OL="http://ws.apache.org/ns/synapse" xmlns:TL="www.tuplelist.com" xmlns:T="http://ws.apache.org/ns/synapse">
<xsl:param name="tl-url" select="'test2016060901.xml'"/>
<xsl:variable name="TL" select="document($tl-url)" />
<xsl:template match="OL:orderlist">
<orderlist>
<xsl:for-each select="OL:order">
<xsl:copy>
<xsl:copy-of select="node()"/>
<xsl:variable name="sta" select="OL:sender/OL:town"/>
<xsl:variable name="dest" select="OL:recipient/OL:town"/>
<xsl:copy-of select="$TL/TL:tuplelist/T:tuple[starts-with(OL:start, $sta) and starts-with(OL:destination, $dest)]/T:distance"/>
</xsl:copy>
</xsl:for-each>
</orderlist>
</xsl:template>
</xsl:stylesheet>
转换
<TU:tuplelist xmlns:TU="www.tuplelist.com">
<tuple xmlns="http://ws.apache.org/ns/synapse">
<start>New York, Country</start>
<destination>Phoenix, SomeCountry</destination>
<distance>190 km</distance>
</tuple>
<!-- more <tuple> Elements here -->
</TU:tuplelist>
和
<orderlist xmlns="http://ws.apache.org/ns/synapse">
<order>
<nr>Transportauftrag</nr>
<sender>
<name>somename</name>
<street>somestreet</street>
<number>somenumber</number>
<zip>somezip</zip>
<town>New York</town>
<country>somecountry</country>
</sender>
<recipient>
<name>aname</name>
<street>astreet</street>
<number>anumber</number>
<zip>azip</zip>
<town>Phoenix</town>
<country>acountry</country>
</recipient>
</order>
<!-- more <order> elements here -->
</orderlist>
进入
<orderlist xmlns:OL="http://ws.apache.org/ns/synapse" xmlns:TL="www.tuplelist.com" xmlns:T="http://ws.apache.org/ns/synapse"><order xmlns="http://ws.apache.org/ns/synapse">
<nr>Transportauftrag</nr>
<sender>
<name>somename</name>
<street>somestreet</street>
<number>somenumber</number>
<zip>somezip</zip>
<town>New York</town>
<country>somecountry</country>
</sender>
<recipient>
<name>aname</name>
<street>astreet</street>
<number>anumber</number>
<zip>azip</zip>
<town>Phoenix</town>
<country>acountry</country>
</recipient>
<distance xmlns:TU="www.tuplelist.com">190 km</distance></order></orderlist>
我想你想通过
来清理一些命名空间<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:OL="http://ws.apache.org/ns/synapse" xmlns:TL="www.tuplelist.com"
exclude-result-prefixes="TL">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="tl-url" select="'test2016060901.xml'"/>
<xsl:variable name="TL" select="document($tl-url)"/>
<xsl:template match="OL:orderlist">
<xsl:copy>
<xsl:for-each select="OL:order">
<xsl:copy>
<xsl:copy-of select="node()"/>
<xsl:variable name="sta" select="OL:sender/OL:town"/>
<xsl:variable name="dest" select="OL:recipient/OL:town"/>
<xsl:copy-of
select="$TL/TL:tuplelist/OL:tuple[starts-with(OL:start, $sta) and starts-with(OL:destination, $dest)]/OL:distance"
/>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但找到了匹配。