XSL从基于属性值的节点获取值匹配

时间:2018-05-30 21:28:04

标签: xslt

我几乎是xsl的新手。当前面临将以下示例xml转换为所需输出的挑战。

示例XML:

<root>
<types>
<entity-type>
<field-type identifier="FieldType1" proxy-ref="TypeA">
    <object-name>aclProxy</object-name>
    <persistence-class-name>java.lang.Long</persistence-class-name>
  </field-type>
  <field-type identifier="FieldType2" proxy-ref="TypeB">
    <object-name>aclName</object-name>
    <persistence-class-name>java.lang.String</persistence-class-name>
  </field-type>
 </entity-type>
 </types>
 <custom>
<category identifier="parent" order="1">
  <name>%category.parent</name>
</category>
<category identifier="texts" order="2">
  <name>%category.Texts</name>
</category>
<field identifier="ArticleID" category-ref="parent" field-type-ref="FieldType1" proxy-entity-ref="ABC">
    <name>%field.name</name>
    <description>%field.Article.description</description>
  </field>
  <field identifier="ArticleName" category-ref="texts" field-type-ref="FieldType2" proxy-entity-ref="ABCD">
    <name>%field.name.text</name>
    <description>%field.Articletext.description</description>
  </field>
  </custom>
  </root>

输出

    <field identifier="ArticleID">
    <name>%field.name</name>
    <description>%field.Article.description</description>
    <category-ref-name>%category.parent</category-ref-name>
    <field-type-ref>Long</field-type-ref>
    <proxy-entity-ref>TypeA</proxy-entity-ref>
    </field>
    <field identifier="ArticleName" >
    <name>%field.name.text</name>
    <description>%field.Articletext.description</description>
    <category-ref-name>%category.Texts</category-ref-name>
    <field-type-ref>String</field-type-ref>
    <proxy-entity-ref>TypeB</proxy-entity-ref>
    </field>

XSLT 我一直在尝试:

 <xsl:stylesheet version="1.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:key name="category" match="category" use="@identifier" />
  <xsl:key name="field" match="field" use="@category-ref" />

  <xsl:apply-templates select="custom[not(key('field',category/@identifier))]"/>

  <xsl:template match="/">
  <xsl:text>something</xsl:text>
  <xsl:value-of select="category/@identifier"/>
  <xsl:apply-templates select="."/>
  </xsl:template>

  <xsl:template match="/">
  <xsl:value-of select="field/@identifier"/>
  <xsl:variable name="categoryparam" select="key('category', field/@category-ref)" />
  <xsl:if test="$categoryparam">
  <xsl:apply-templates select="$categoryparam"/>
  <xsl:text>something</xsl:text>
  </xsl:if>
  </xsl:template>
  </xsl:stylesheet>

基本上输出应该只包含字段,引用属性并获取节点值。

非常感谢任何帮助。 提前谢谢。

1 个答案:

答案 0 :(得分:1)

让我们从这两个键开始:

<xsl:key name="kCategory" match="category" use="@identifier" />
<xsl:key name="kFieldID" match="field-type" use="@identifier" />

稍后您将需要categoryfield-type个节点中的值。

此模板:

<xsl:template match="/">
    <xsl:apply-templates select="root/custom/field"/>
</xsl:template>

将输出目标field节点

使模板与field节点匹配以进一步操作输出:

<xsl:template match="field">
    <xsl:copy>
        <!-- copies the identifier attribute and all children -->
        <xsl:copy-of select="@identifier|node()"/>
        <category-ref-name>
            <!-- gets the child name of the target category node
                 that matches the category-ref attribute -->
            <xsl:value-of select="key('kCategory', @category-ref)/name"/>
        </category-ref-name>
        <field-type-ref>
            <!-- gets the child persistence-class-name of the target
                 field-type node that matches the field-type-ref attribute,
                 with further substring manipulations -->
            <xsl:value-of select="substring-after(key('kFieldID', @field-type-ref)/persistence-class-name, 'java.lang.')"/>
        </field-type-ref>
        <proxy-entity-ref>
            <!-- gets the attribute proxy-ref of the target
                 field-type node that matches the field-type-ref
                 attribute -->
            <xsl:value-of select="key('kFieldID', @field-type-ref)/@proxy-ref"/>
        </proxy-entity-ref>
    </xsl:copy>
</xsl:template>

整个样式表如下:

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

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

    <xsl:key name="kCategory" match="category" use="@identifier" />
    <xsl:key name="kFieldID" match="field-type" use="@identifier" />

    <xsl:template match="/">
        <xsl:apply-templates select="root/custom/field"/>
    </xsl:template>

    <xsl:template match="field">
        <xsl:copy>
            <xsl:copy-of select="@identifier|node()"/>
            <category-ref-name>
                <xsl:value-of select="key('kCategory', @category-ref)/name"/>
            </category-ref-name>
            <field-type-ref>
                <xsl:value-of select="substring-after(key('kFieldID', @field-type-ref)/persistence-class-name, 'java.lang.')"/>
            </field-type-ref>
            <proxy-entity-ref>
                <xsl:value-of select="key('kFieldID', @field-type-ref)/@proxy-ref"/>
            </proxy-entity-ref>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

查看实际操作(http://xsltfiddle.liberty-development.net/gWmuiJc)。