XSLT中的依赖关系图遍历,用于复制XML模型的相关元素

问题描述 投票:0回答:1

我想通过解决以下问题来展示XSL在数据探索方面的强大功能:给定一个描述某种“实体冲突”模型的xml文件,并为该模型中的一个实体提供一个名称(假设XML模式的属性用作标识符),我想要一个转换以产生一个新的XML包含给定实体的模型,以及根据该给定实体的“依赖关系的传递闭包”的所有亲戚。

例如,输入的XML模型是

<root>
    <!-- my model is made of 3 entities : leaf, composite and object -->
    <!-- the xml elements are <leaves>, <composites> and <objects> are just placeholders for these entities -->
    <!-- These placeholders are exepected to be in that order in the output as well as in the input (Schema constraints) -->
    <leaves>
        <!-- A, B, C are 3 types of different leaf nodes with their proper semantic in the model -->
        <A name="f1" others="oooo"/>
        <A name="f2" others="xxxx"/>
        <B name="f3" others="ssss"/>
        <C name="f4" others="gggg"/>    
    </leaves>
    <composites>
        <!-- composites containes only struct and union element -->
        <struct name="structB" others="yyyy">
            <!-- composite pattern, struct can embed struct in a tree-ish fashion -->
            <sRef name="s6" nameRef="structA"/>
            <!-- order of declaration does not matter !!! here in the XML, structA is not yet declared but file is valid -->
            <uRef name="u7" nameRef="unionX"/>
        </struct>
        <!-- union is another kind of composition -->
        <union name="unionX" others="rrrr">
            <vRef name="u3" nameRef="f3" others="jjjj">
            <vRef name="u4" nameRef="f2" others="pppp">
        </union>
        <struct name="structA" others="hhhh">
            <vRef name="v1" nameRef="f1" others="jjjj">
            <vRef name="v2" nameRef="f4" others="pppp">
        </struct>
    </composites>
    <objects>
        <object name="objB" others="tttt">
            <field name="field1" nameRef="unionX" others="qqqq"/>
            <field name="field2" nameRef="f2" others="cccc"/>
        </object>
        <object name="objC" others="nnnn">
            <field name="fieldX" nameRef="structB" others="uuuu"/>
            <field name="fieldY" nameRef="" others="mmmm"/>
        </object>
        <object name="objMain" others="nnnn">
            <field name="fieldY" nameRef="structA" others="mmmm"/>
            <field name="fieldY" nameRef="f3" others="mmmm"/>
            <field name="object4" nameRef="objB" others="wwwww"/>
        </object>
    </objects>
<root>

我想要一个给定名称的转换,该转换创建模型的副本,该副本仅包含与该名称的元素有关的信息以及由nameRef属性描述的依赖关系。

因此元素“ field1”的输出将是

<root>
    <leaves>
        <A name="f1" others="oooo"/>
    </leaves>
    <!-- composites and objects placeholders shall be copied even when no elements in the graph traversal -->
    <composites/>
    <objects/>
<root>

而“ objB”的预期输出将是

<root>
    <leaves>
        <!-- element "f2" shall be copied only once in the output, althought the node is encountered twice in the traversal of "objB" tree :
            - "f2" is referenced under "field2" of "obj2"
            - "f2" is referenced under "u4" of "unionX" that is referencd under "field1" of "obj2"      
        -->
        <A name="f2" others="xxxx"/>
        <B name="f3" others="ssss"/>
    </leaves>
    <composites>
        <union name="unionX" others="rrrr">
            <vRef name="u3" nameRef="f3" others="jjjj">
            <vRef name="u4" nameRef="f2" others="pppp">
        </union>
    <composites>
    <objects>
        <object name="objB" others="tttt">
            <field name="field1" nameRef="unionX" others="qqqq"/>
            <field name="field2" nameRef="f2" others="cccc"/>
        </object>
    </objects>
<root>

依此类推。

从现在开始,我在基本的XSL上锻炼,但由于以下原因,并不令人满意:

  • 我的转换不是基于“身份规则”进行复制的基础
  • 我的转换在遇到匹配实体时使用xsl:copy-of,但这会破坏设计并违反XSD架构
  • 输出文件与输入的XML模式定义不兼容,主要是因为xsl:copy-of违反了XML元素的遍历
  • 我的转换在依赖关系的可传递闭包中多次出现时,在输出中使重复的实体

我对完成此操作的优雅方式只有一些感觉和“想法”。

  • 从“身份转换”模板开始,以尊重输入的Xml架构
  • 使用分组/按键排序
  • 为此实现某种“ Muenchian方法”(实际上不确定,也许仅针对XSLT 1.0)

为简单起见,您可以做以下假设:

  • 它们没有循环依赖的情况(可以执行树行走)
  • nameRef /名称由XSD中的“键”进行交叉检查,以便在输入中引用正确
  • 要搜索的元素的输入参数“名称”存在于输入xml模型中(尽管在这种情况下生成“空”有效xml会很好)

“空” xml输出模型应如下所示(由于架构约束)

<root>
    <leaves/>
    <composites/>
    <objects/>
<root> 

要完成:我当前使用的xslt处理器是Saxon XSLT proc,XSLT的版本是2.0感谢您的帮助...我不会给您不令我感到骄傲的xsl,但如果它对您有帮助,我会...

xml xslt xslt-2.0 saxon xslt-grouping
1个回答
0
投票

我尝试实现“对于给定名称,仅使用与该名称的元素相关的信息以及由nameRef属性描述的依赖项的信息创建模型的副本的转换,位于https://xsltfiddle.liberty-development.net/gWEamLs/1,[C0 ],https://xsltfiddle.liberty-development.net/gWEamLs/2,如您所见,它具有键找到的引用元素,但在树的下方缺少一些元素。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.