使用 XSL 函数动态检索 XML 值 [英] retrieving XML value dynamically using XSL function

查看:22
本文介绍了使用 XSL 函数动态检索 XML 值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我输入的 xml 文件看起来像

my input xml file looks like

<root>
  <sub>
    <element1 value="abc"/>
        <element2 value="123"/>
  </sub>
  <sub1>
    <element1 value="ert"/>
    <element2 value="abc"/>
  </sub1>
</root>

我需要一个 XSLT 函数,它读取下面的 XML 文件并从上面的文件中提取在 map/domain/instance/@xpath 中指定的 xpath 表达式值

i need an XSLT function which reads below XML file and pulls the xpath expression value specified at map/domain/instance/@xpath from above file

<map>
  <domain>
    <instance xpath="root/sub/element1/@value" length="2"/>
  </domain>
  <domain>
        <instance xpath="root/sub1/element2/@value" length="3"/>
  </domain>
</map>

我需要一个 xslt 函数,它根据传入的 xml 文件检查为每个 xpath 表达式指定的长度.

I need a xslt function which checks the length specified for each xpath expression against the incoming xml file.

如果它在长度上失败,它应该返回 false.

if it fails on length it should retrun false.

推荐答案

这个 XSLT 1.0 样式表:

This XSLT 1.0 stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:variable name="document">
        <root>
            <sub>
                <element1 value="abc"/>
                <element2 value="123"/>
            </sub>
            <sub1>
                <element1 value="ert"/>
                <element2 value="abc"/>
            </sub1>
        </root>
    </xsl:variable>
    <xsl:template match="map/domain/instance" name="walker">
        <xsl:param name="path" select="@xpath"/>
        <xsl:param name="context"
               select="document('')/*/xsl:variable[@name='document']"/>
        <xsl:choose>
            <xsl:when test="contains($path,'/')">
                <xsl:call-template name="walker">
                    <xsl:with-param name="path"
                              select="substring-after($path,'/')"/>
                    <xsl:with-param name="context"
                      select="$context/*[name()=substring-before($path,'/')]"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:when test="starts-with($path,'@')">
                <xsl:value-of select="concat(
                                        string-length(
                                          $context/attribute::*
                                             [name()=substring($path,2)])
                                        =@length,
                                        '&#xA;')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat(
                                        string-length(
                                          $context/*[name()=$path])
                                        =@length,
                                        '&#xA;')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

输出:

false
true

编辑:XSLT 2.0 解决方案.此样式表:

Edit: XSLT 2.0 solution. This stylesheet:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="example.org">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:variable name="document">
        <root>
            <sub>
                <element1 value="abc"/>
                <element2 value="123"/>
            </sub>
            <sub1>
                <element1 value="ert"/>
                <element2 value="abc"/>
            </sub1>
        </root>
    </xsl:variable>
    <xsl:template match="map/domain/instance">
        <xsl:sequence select="my:xpath(@xpath,$document)
                                   /string(string-length() =
                                           current()/@length)"/>
        <xsl:text>&#xA;</xsl:text>
    </xsl:template>
    <xsl:function name="my:xpath" as="item()*">
        <xsl:param name="path" as="xs:string"/>
        <xsl:param name="context" as="node()*"/>
        <xsl:variable name="steps" as="item()*"
                      select="tokenize($path,'/')"/>
        <xsl:variable name="this" as="item()*"
                      select="$context/(*[if ($steps[1]='*')
                                          then true()
                                          else name()=$steps[1]]|
                                        @*[if ($steps[1]='@*')
                                          then true()
                                          else name() =
                                               substring($steps[1],2)])"/>
        <xsl:choose>
            <xsl:when test="count($steps)>1">
                <xsl:sequence
                    select="my:xpath(string-join($steps[position()!=1],
                                                 '/'),
                                     $this)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:sequence select="$this"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:function>
</xsl:stylesheet>

输出:

false
true

编辑 2:有所改进.所以现在,有了这个输入:

Edit 2: A bit improven. So now, with this input:

<map>
    <domain>
        <instance xpath="root/sub/element1/@*" length="2"/>
    </domain>
    <domain>
        <instance xpath="root/sub/*/@value" length="3"/>
    </domain>
</map>

输出:

false
true true

这篇关于使用 XSL 函数动态检索 XML 值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆