检查2个不同xml文档的值

时间:2012-12-17 18:36:16

标签: xml xslt nextsibling

我正在使用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>

2 个答案:

答案 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>

许多问题:

  1. 两个文档都没有名为cell的顶级元素 - 而不是绝对表达式,您必须使用相对的元素:
  2. .....

    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()"/>