我正在使用2个XML文档,如果匹配变量,则尝试从一个文档中获取值到另一个文档中。第一个XML文档是转换后的电子表格,格式如下:
<Doc1>
<row>
<cell>VA15</cell>
<cell>wr23</cell>
</row>
<row>
<cell>VA45</cell>
<cell>wr27</cell>
</row> <row>
<cell>VA78</cell>
<cell>wr24</cell>
</row>
</Doc1>
第二个XML文档较长,其中有一个id
元素与电子表格的一部分匹配:
<Doc2>
<p> text text text
<id>wr23</id>
</p>
</Doc2>
我正在尝试使用我的xslt转换进行测试,以查看id
元素是否与doc1中cell
的值相匹配,它会提取前一个cell
的值。在这种情况下,我希望xslt转换输出“VA15”。我尝试过以下代码的各种排列但没有成功,有没有人有任何想法?
<xsl:for-each select="document('Doc1.xml')//row">
<xsl:if test="/cell=//id'">
<xsl:value-of select="/preceding-sibling::cell"/>
</xsl:if>
</xsl:for-each>
答案 0 :(得分:1)
根据Dimitre的回答,您可以使用key()
(用于快速查找)和call-template
将此“查找IDREF”模式抽象为单独的模板:
<强> ID-lookup.xsl 强>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="id-lookup-doc">Doc1.xml</xsl:param>
<xsl:variable name="id-to-value-doc" select="document($id-lookup-doc)"/>
<xsl:key name="value-for-id"
match="/Doc1/row/cell[1]"
use="../cell[2]" />
<xsl:template name="value-for-id">
<xsl:param name="id"/>
<!-- for-each is just to change the context
to limit results from key() to the lookup document -->
<xsl:for-each select="$id-to-value-doc">
<xsl:value-of select="key('value-for-id', $id)"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<强>更换-ID与 - value.xsl 强>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="id-lookup.xsl"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="id">
<val>
<xsl:apply-templates select="@*"/>
<xsl:call-template name="value-for-id">
<xsl:with-param name="id" select="text()"/>
</xsl:call-template>
</val>
</xsl:template>
</xsl:stylesheet>
当您通过xslt处理器运行此操作时,您将获得所有<id>
元素替换为<val>
的文档及相应的值。
使用xsltproc
,您可以这样运行:
xsltproc id-with-value.xsl Doc2.xml myOtherDoc.xml
您甚至可以使用xslt参数更改查找文档:
xsltproc --stringparam id-lookup-doc MyOtherSetOfIdsAndValues.xml id-with-value.xsl Doc2.xml
无论您使用何种XSLT处理器,都可以通过某种方式指定模板参数。
答案 1 :(得分:0)
<xsl:for-each select="document('Doc1.xml')//row"> <xsl:if test="/cell=//id'"> <xsl:value-of select="/preceding-sibling::cell"/> </xsl:if> </xsl:for-each>
许多问题:
cell
的顶级元素 - 而不是绝对表达式,您必须使用相对的元素:.....
cell = //id
和
preceding-sibling::cell
因为文档节点没有兄弟姐妹。
0.2。具有名为cell
的元素的文档没有名为id
的元素。当XPath表达式引用多个文档时,必须显式引用除一个文档之外的所有文档。通过所有更正,您的代码将变为:
<xsl:variable name="vthisDoc" select="/"/>
<xsl:for-each select="document('Doc1.xml')//row">
<xsl:if test="cell=$vthisDoc//id'">
<xsl:value-of select="preceding-sibling::cell"/>
</xsl:if>
</xsl:for-each>
最后,所有这些都可以写成:
<xsl:copy-of select=
"document('Doc1.xml')//row[cell=$vthisDoc//id]/preceding-sibling::cell[1]/text()"/>