我有以下输入:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:abc="http://abc.def"
targetNamespace="http://abc.def"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<simpleType name="StatusCategoryId">
<restriction base="string"/>
</simpleType>
<complexType name="StatusCategory">
<sequence>
<element name="statusCategoryId"
type="abc:StatusCategoryId"/>
<element name="nameEN" type="string"/>
<element name="nameCZ" type="string"/>
<element name="claimCategoryId" type="string"/>
</sequence>
</complexType>
<complexType name="StatusCategoryCollection">
<sequence>
<element name="statusCategoryInstance"
type="abc:StatusCategory"
minOccurs="0"
maxOccurs="unbounded"/>
</sequence>
</complexType>
</schema>
我想要的输出是
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:abc="http://abc.def"
targetNamespace="http://abc.def"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<simpleType name="StatusCategoryId">
<restriction base="string"/>
</simpleType>
<complexType name="StatusCategory">
<sequence>
<element name="statusCategoryId">
<simpleType name="StatusCategoryId">
<restriction base="string"/>
</simpleType>
</element>
<element name="nameEN" type="string"/>
<element name="nameCZ" type="string"/>
<element name="claimCategoryId" type="string"/>
</sequence>
</complexType>
<complexType name="StatusCategoryCollection">
<sequence>
<element name="statusCategoryInstance"
minOccurs="0"
maxOccurs="unbounded">
<complexType name="StatusCategory">
<sequence>
<element name="statusCategoryId">
<simpleType name="StatusCategoryId">
<restriction base="string"/>
</simpleType>
</element>
<element name="nameEN" type="string"/>
<element name="nameCZ" type="string"/>
<element name="claimCategoryId" type="string"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</schema>
为此,我试图找到xs:*(具有W3C架构命名空间的任何东西),其属性@name
具有与当前元素的@type
属性相同的值。
apply-templates select = "$var"
。但每当我尝试使用这样的元素分配变量时,转换就会失败,因为该变量未设置:(
EDITED xslt begin
<xsl:variable name="test1">
<xsl:copy-of select="root(.)//xs:*[@name= $type]"/>
</xsl:variable>
<!-- this variables above are here only out of context,
not real position in xslt code -->
<xsl:function name="pk:test">
<xsl:param name="this"/>
<xsl:variable name="test" select="in-scope-prefixes($this)"/>
<xsl:element name="namespaces-root">
<xsl:for-each select="$test">
<xsl:element name="namespace">
<xsl:element name="prefix">
<xsl:value-of select="."/>
</xsl:element>
<xsl:element name="ns">
<xsl:value-of
select="namespace-uri-for-prefix(.,$this)"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:function>
<xsl:function name="pk:childsHasType">
<xsl:param name="this"/>
<xsl:variable name="testX"
select="substring-before($this/@type,':')"/>
<xsl:choose>
<xsl:when test="$this/*">
<xsl:for-each select="$this/*">
<xsl:value-of select="concat(
$testX != $var/namespace
[ns=$defaultSchemaNS]/prefix,
string-join(pk:childsHasType(.),'|'))"/>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="$testX != $var/namespace
[ns=$defaultSchemaNS]/prefix"/>
</xsl:otherwise>
</xsl:choose>
</xsl:function>
<xsl:variable name="var" select="pk:test(./child::*[1])"/>
<xsl:variable name="defaultSchemaNS"
select="'http://www.w3.org/2001/XMLSchema'"/>
<xsl:template match="xs:element">
<xsl:variable name="test0"
select="substring-before(@type,':')"/>
<xsl:variable name="differentTypeTest"
select="string-join(pk:childsHasType(.), ', ')"/>
<xsl:choose>
<xsl:when test="contains($differentTypeTest,'true')">
<xsl:variable name="type" select="xs:string"
select="if (contains(@type, ':'))
then substring-after(@type,':')
else @type"/>
<xsl:element name="element"
namespace="{$var/namespace[prefix=$test]/ns}">
<xsl:copy-of select="@*[name()!='type']"/>
<xsl:text> </xsl:text>
<!--next xsl copy to output works flawlessly-->
<xsl:copy-of select="//node()[./@name = $type]"/>
<!-- next variable here is unusable :( -->
<xsl:variable name="test1">
<xsl:copy-of select="root(.)//xs:*[@name= $type]"/>
</xsl:variable>
<xsl:text> </xsl:text>
<xsl:apply-templates select="child::node()"/>
<!--<xsl:copy-of select="child::*"/>-->
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
EDITED xslt end
然而,当我用真正的字符串检查它时,它可以完美地工作......
<xsl:variable name="test2">
<xsl:copy-of select="root(.)
//xs:*[@name= 'StatusCategoryId']"/>
</xsl:variable>
我认为原因可能在于$ type变量的设置,但是我已经尝试了几乎所有东西,似乎没有任何工作,因为我无法根据变量创建一个xpath:(
答案 0 :(得分:2)
我无法理解您的XSLT尝试做什么,所以我纯粹通过比较输入和输出XML来接近它。
看起来您希望按名称查找simpleType
和complexType
元素,因此您可以将它们输出到XML中的其他位置。这可能是使用密钥
<xsl:key name="complexType" match="xs:simpleType|xs:complexType" use="@name" />
然后只是匹配引用这些类型之一的element
元素的情况
<xsl:template match="xs:element[key('complexType', substring-after(@type, ':'))]">
(我不确定你是否也需要在这里查看abc:
前缀)
然后,要输出其他类型的详细信息,您只需使用密钥
即可<xsl:apply-templates select="key('complexType', substring-after(@type, ':'))" />
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="complexType" match="xs:simpleType|xs:complexType" use="@name" />
<xsl:template match="xs:element[key('complexType', substring-after(@type, ':'))]">
<xsl:copy>
<xsl:apply-templates select="@*[local-name() != 'type']"/>
<xsl:apply-templates select="key('complexType', substring-after(@type, ':'))" />
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
如果我们假设我们理解任务和目标词汇表(XSD),那么您正在做的事情有很多问题。例如,您的预期输出不是有效的模式,因为本地simpleType或complexType不能具有name属性;还有C.M.Sp-McQ提到的问题:如果你知道你的输入是使用XSD允许的有限子集,这可能不是问题。
然而,将其视为任意XML文档的转换,我很难确切地看到问题所在。你说&#34;转换失败,因为该变量未设置&#34;,但这听起来不像撒克逊错误消息,它听起来像是你的错误消息的释义。您说变量test1不可用,但您没有显示任何试图使用它的代码。如果你准确地告诉我们你在做什么以及到底出了什么问题,那么帮助你会更容易,最好给我们一个完整的(但是很少的)源文件和样式表,这样我们就可以自己试一试。
对于SO思想警察来说,我知道这不是一个答案,但是发表评论的时间太长了。