在xslt 2.0中组合两个xml

时间:2013-11-04 10:27:04

标签: xml xslt xslt-2.0

我有两个XML,其中一个包含条件,另一个xml包含必须根据条件评估分配给结果XML的错误代码列表。

Conditions.xml

<Validations>   
<Condition-1>UPDATE-IND!=A</Condition-1>   
<Condition-2>DUP-OVERRIDE=B</Condition-2>   
<Condition-3>TYPE-RECORD!=R</Condition-3>
</Validations>

ErrorList.xml

<ErrorList>
<error>
    <errorcode>1</errorcode>
    <errordescription>UPDATE INDICATOR.</errordescription>
</error>
<error>
    <errorcode>2</errorcode>
    <errordescription>SHOULD NOT BE BLANK.</errordescription>
</error>
<error>
    <errorcode>3</errorcode>
    <errordescription>NOT IN LIST</errordescription>
</error>
<error>
    <errorcode>4</errorcode>
    <errordescription>PARSE ERROR.</errordescription>
</error>

输入XML:

<a>
    <c>
        <UPDATE-IND>A</UPDATE-IND>
        <DUP-OVERRIDE>B</DUP-OVERRIDE>
        <TYPE-RECORD>R</TYPE-RECORD>
    </c>
</a>

在XSLT中,生成的xml应该像

当条件1为真时(来自Conditions.xml),应在结果xml中显示来自ErrorList.xml的第一组错误代码。同样,对于满足的所有条件,相关的错误节点应该显示在我的最终xml中。

如何为此编写XSLT?我一直在尝试使用document()函数,但无法弄清楚如何同时遍历所有条件和错误代码以形成最终的XML。

注意:我在我的Tibco BW中尝试使用Saxon-B XSLT 2.0作为转换引擎。

新逻辑:

我没有组合两个XML,而是试图使用包含条件和错误代码的单个xml。

输入XML保持不变。

条件XML:

<ns0:root xmlns:ns0 = "http://www.tibco.com/schemas/Validation.xsd">
<ns0:subElement1 ID = "id">
    <ns0:subElement2 ID = "id">
        <ns0:subElement3 ID = "id">
            <ns0:subElement4 ID = "id">
                <ns0:subElement5 cond = "1">
                    <ns0:conditions>1=1</ns0:conditions>
                    <ns0:errorcode>001</ns0:errorcode>
                </ns0:subElement5>
                <ns0:subElement5 cond = "2">
                    <ns0:conditions>2=2</ns0:conditions>
                    <ns0:errorcode>002</ns0:errorcode>
                </ns0:subElement5>
                <ns0:subElement5 cond = "3">
                    <ns0:conditions>3!=3</ns0:conditions>
                    <ns0:errorcode>003</ns0:errorcode>
                </ns0:subElement5>
            </ns0:subElement4>
        </ns0:subElement3>
    </ns0:subElement2>
</ns0:subElement1>

现在我正在尝试获取条件,对其进行评估并从相同的xml中获取相关的错误代码。

注意: conditions.xml作为输入参数传递给XSLT。

1 个答案:

答案 0 :(得分:3)

如果您想根据位置选择元素,请使用

<xsl:param name="error-url" select="'ErrorList.xml'"/>

<xsl:variable name="errors" select="doc($error-url)/ErrorList/error"/>

<xsl:template match="Validations">
  <xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="Validations/*">
  <xsl:variable name="pos" select="position()"/>
  <xsl:if test="saxon:evaluate(.)">
    <xsl:copy-of select="$errors[$pos]"/>
  </xsl:if>
</xsl:template>

这是一个更完整的样本。假设我们有主要输入

<a>
    <c>
        <UPDATE-IND>A</UPDATE-IND>
        <DUP-OVERRIDE>B</DUP-OVERRIDE>
        <TYPE-RECORD>R</TYPE-RECORD>
    </c>
</a>

test2013110502.xml

<Validations>   
<Condition-1>UPDATE-IND!='A'</Condition-1>   
<Condition-2>DUP-OVERRIDE='B'</Condition-2>   
<Condition-3>TYPE-RECORD!='R'</Condition-3>
</Validations>

(注意对样本的更改,右侧有字符串文字)和文件test2013110503.xml

<ErrorList>
<error>
    <errorcode>1</errorcode>
    <errordescription>UPDATE INDICATOR.</errordescription>
</error>
<error>
    <errorcode>2</errorcode>
    <errordescription>SHOULD NOT BE BLANK.</errordescription>
</error>
<error>
    <errorcode>3</errorcode>
    <errordescription>NOT IN LIST</errordescription>
</error>
<error>
    <errorcode>4</errorcode>
    <errordescription>PARSE ERROR.</errordescription>
</error>
</ErrorList>

样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:saxon="http://saxon.sf.net/"
  exclude-result-prefixes="xs saxon">

<xsl:param name="conditions-url" as="xs:string" select="'test2013110502.xml'"/>
<xsl:param name="conditions" as="document-node()" select="doc($conditions-url)"/>

<xsl:param name="error-url" as="xs:string" select="'test2013110503.xml'"/>
<xsl:param name="errors" as="document-node()" select="doc($error-url)"/>

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:template match="c">
  <errors>
    <xsl:apply-templates select="$conditions/Validations/*">
      <xsl:with-param name="context" select="current()"/>
    </xsl:apply-templates>
  </errors>
</xsl:template>

<xsl:template match="Validations/*">
  <xsl:param name="context"/>
  <xsl:variable name="pos" select="position()"/>
  <xsl:apply-templates select="$context" mode="eval">
    <xsl:with-param name="expression" select="string(current())"/>
    <xsl:with-param name="pos" select="$pos"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="c" mode="eval">
  <xsl:param name="expression"/>
  <xsl:param name="pos"/>
  <xsl:if test="saxon:evaluate($expression)">
    <xsl:copy-of select="$errors/ErrorList/error[$pos]"/>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

输出

<errors>
   <error>
      <errorcode>2</errorcode>
      <errordescription>SHOULD NOT BE BLANK.</errordescription>
   </error>
</errors>

使用支持EXSLT dyn:evaluate功能的XSLT 1.0处理器应该可以实现相同的目标:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:dyn="http://exslt.org/dynamic"
  exclude-result-prefixes="dyn">

<xsl:param name="conditions-url" select="'test2013110502.xml'"/>
<xsl:param name="conditions" select="document($conditions-url)"/>

<xsl:param name="error-url" select="'test2013110503.xml'"/>
<xsl:param name="errors" select="document($error-url)"/>

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:template match="c">
  <errors>
    <xsl:apply-templates select="$conditions/Validations/*">
      <xsl:with-param name="context" select="current()"/>
    </xsl:apply-templates>
  </errors>
</xsl:template>

<xsl:template match="Validations/*">
  <xsl:param name="context"/>
  <xsl:variable name="pos" select="position()"/>
  <xsl:apply-templates select="$context" mode="eval">
    <xsl:with-param name="expression" select="string(current())"/>
    <xsl:with-param name="pos" select="$pos"/>
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="c" mode="eval">
  <xsl:param name="expression"/>
  <xsl:param name="pos"/>
  <xsl:if test="dyn:evaluate($expression)">
    <xsl:copy-of select="$errors/ErrorList/error[$pos]"/>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

我得到了结果

<?xml version="1.0"?>
<errors>
  <error>
    <errorcode>2</errorcode>
    <errordescription>SHOULD NOT BE BLANK.</errordescription>
  </error>
</errors>

xsltproc

Using libxml 20708, libxslt 10126 and libexslt 815
xsltproc was compiled against libxml 20706, libxslt 10126 and libexslt 815
libxslt 10126 was compiled against libxml 20706
libexslt 815 was compiled against libxml 20706
在Windows上