【问题标题】:XSLT: Copy Where current type value equals the name of an elementXSLT:复制其中当前类型值等于元素名称
【发布时间】:2009-07-08 18:28:13
【问题描述】:

使用this file 作为源,我需要从本地源文件或导入中注明的相关文件中检索元素。 type 值使用冒号分隔两个值 - substring-before(@type, ':') 告诉我要引用哪个文件; substring-after(@type, ':') 是我需要以相同方式复制和迭代其内容的文件中元素的名称。

示例:我想要名称为“PersonType”的 xs:complexType,因此我使用副本来获取它及其子项。下一步是查看那些子元素——对于那些是 xs:element 的子元素,我想检索类型值 ("AcRec:HighSchoolType") 中引用的元素。 “AcRec”告诉我需要使用哪个 xsd,所以我知道我会在该 xsd 中找到名称值为“HighSchoolType”的东西。查看 AcRec xsd,我知道“HighSchoolType”是一个 xs:complexType(我已经定义了要处理的模板),所以我应该看到输出。

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:core="urn:org:pesc:core:CoreMain:v1.2.0" xmlns:AcRec="urn:org:pesc:sector:AcademicRecord:v1.1.0">
    <xsl:apply-templates select="//xs:complexType[@name='PersonType']" />       
</xs:schema>
</xsl:template> 

<xsl:template match="xs:complexType">
    <xsl:copy>
        <xsl:copy-of select="node()[not(xs:annotation | xs:restriction)]|@*"/>
    </xsl:copy>
    <xsl:apply-templates select=".//xs:element" />
</xsl:template>

<xsl:template match="xs:simpleType">
    <xsl:copy>
        <xsl:copy-of select="node()|@*"/>
    </xsl:copy>
</xsl:template> 

<xsl:template match="xs:element">
    <xsl:choose>
        <xsl:when test="substring-before(@type, ':') = 'AcRec'">
            <xsl:text>AcRec</xsl:text>
            <xsl:apply-templates select="document('[local file path]AcademicRecord_v1.3.0.xsd')//*[@name=substring-after(@type, ':')]" />
        </xsl:when>                     
    </xsl:choose>
</xsl:template>

所需的输出如下所示:

<xs:complexType name="PersonType">
  <xs:sequence>
    <xs:element name="HighSchool" type="AcRec:HighSchoolType" minOccurs="0">
  </xs:sequence>
</xs:complexType>
<xs:complexType name="HighSchoolType">
  <xs:sequence>
    <xs:element name="OrganizationName" type="core:OrganizationNameType"/>
    <xs:group ref="core:OrganizationIDGroup" minOccurs="0"/>
  </xs:sequence>
</xs:complexType>

当我成功输入 xsl:when 时,我在查看文档时遗漏了什么? xsl:text 告诉我我在,但后续行没有返回任何输出。

此外,如何在复制 xs:complextType 和 xs:simpleType 元素时排除 xs:annotation 和 xs:restriction 元素的出现?我无法让 dpawson 网站上提到的示例正常工作。

【问题讨论】:

    标签: xslt


    【解决方案1】:

    我不得不说,并且无意冒犯,你的问题真的很难理解;你能再分解一下吗?

    同时,就排除 xs:annotation 和 xs:restriction 元素而言,只需更改您的 copy-of 语句以将它们排除在外:

    <xsl:copy-of select="node()[not(self::xs:annotation or self::xs:restriction)]|@*"/>
    

    ...而您有一个 xsl:choose 元素,其中只有一个 xsl:when 而没有 xsl:otherwise... 您可以使用 xsl:if 元素来简化:

    <xsl:template match="xs:element">
       <xsl:if test="substring-before(@type, ':') = 'AcRec'">
         <xsl:text>AcRec</xsl:text>
           <xsl:apply-templates select="document('[local file path]AcademicRecord_v1.3.0.xsd')//*[@name=substring-after(@type, ':')]" />
       </xsl:if>
    </xsl:template>
    

    经过进一步思考,您的 select 语句可能格式不正确:目前它正在尝试匹配具有与冒号后的 type 属性匹配的 name 属性的任何元素。所以必须匹配

    <element name="text" type="some:text"/>
    

    如果你没有这样的元素,那么你的匹配是空的,所以没有模板运行。

    【讨论】:

    • 我更新了帖子以包含一个示例 - 希望它更清楚。您建议的排除项我没有任何幸运 - 如果有与注释/限制元素相关联的子项,这有关系吗?
    • 我需要它来匹配 而不是 。我解释了 CHOOSE 以捕获当前“some”的各种实例,以便我知道使用 some.xsd 来查找元素 name="text"。
    • 是的...我忘记了注释/限制段中的 self:: 轴。适当修改。
    【解决方案2】:

    问题是:

    <xsl:apply-templates select="document('[local file path]AcademicRecord_v1.3.0.xsd')//*[@name=substring-after(@type, ':')]" />
    

    ...应该是:

    <xsl:variable name="name" select="substring-after(@type, ':')" />
    <xsl:apply-templates select="document('[local file path]AcademicRecord_v1.3.0.xsd')//*[@name=$name]" />
    

    ScottSEA - 你说的比较基于:

    <element name="text" type="some:text"/>
    

    发生的情况是在处理该 XPath 表达式时涉及上下文切换。当你说 //*[@name=substring-after(@type, ':')] 时,你说“将此模板应用于引用的 XSD 文档中的那些元素,这些元素同时具有 @name 和 @type 属性,并且其@name 等于 THEIR @type 的 substring-after ':'。然而,如果您使用变量,您当然会从当前文档中获取 substring-after。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      相关资源
      最近更新 更多