我在这方面工作了一段时间,但无法找到任何类型的工作解决方案。这一切都在xml版本1中。
第一个名为dog_info.xml的文件有类似的东西:
<?xml version"1.0" encoding="UTF-8"?>
<dog_info version="2" dog_num="2" update_time="2013-15-05T14:80:00Z">
<dog_list xml: lang="en">
<dog id="1" name="Nikki" desc="Black with brown spots"/>
<dog id="2" name="Zulu" desc="Oreo color"/>
<dog id="3" name="Tyler" desc="brown dog"/>
<dog id="4" name="Sally" desc="milk color"/>
<dog id="5" name="Joe" desc="brown and grey color"/>
</dog_list>
<dog_list xml:lang="piggylatin">
<dog id="1" name="Nikky" desc="black spots with black and brown spots"/>
<dog id="2" name="apples" desc="green, red or blue apples"/>
<dog id="3" name="Taylor" desc="yellow dog"/>
<dog id="4" name="Susan" desc="a dog"/>
<dog id="5" name="Jason" desc="a cat"/>
</dog_list>
</dog_info>
第二个名为profile.xml的文件有这样的东西:
<?xml version="1.0" encoding="UTF-8"?>
<profile>
<animal-helper>
<animal>
<category>
<rule>
<value>1</value>
<deny />
</rule>
<rule>
<value>2</value>
<deny />
</rule>
</category>
</animal>
</animal-helper>
</profile>
第三个文件就是我写的,但是卡住了。它应该是一个xsl,我可以解析成一个html来显示信息。
profile.xml的值为1且拒绝。如果它是deny,它将与dog_list.xml中的id匹配并检索名称和desc。与任何其他否认相同。
没有<allow />
个标签,只有<deny />
。因此,允许dog_list.xml中所有其余的id。并且应该在html上列出它自己的类别。
我还要注意看看语言是不是“piggylatin”还是“en”它会默认为“en”。任何帮助将不胜感激。
编辑:
实际文件非常大,用于工作。所以我不得不重新创建一些类似于我需要它的东西。
我有类似的东西:
...
<xsl:for-each select="$HELPER/animal/category/rule[name=false()]">
<xsl:variable name="currentValue" select="value/text()"/>
<xsl:variable name="dogValue" select="$DOG_LIST"/>
<xsl:for-each select="$dogValue/dog[@id = $currentValue]">
<xsl:apply-templates/><xsl:if test="position() != last()"><xsl:text disable-output-escaping="yes"><![CDATA[<br />]]></xsl:text></xsl:if>
</xsl:for-each>
</xsl:for-each>
...
编辑2:
上面代码的片段是html表(deny部分)的一部分。看起来应该是这样的:
“拒绝”
尼克
祖鲁
“允许”
泰勒
萨利
乔
因此“Deny”找到值1和2,与id 1和2匹配,并返回名称。 并且“允许”发现id 3,4,5,(因为1和2)被拒绝并返回名称。
<deny />
元素的目的是挑选被拒绝的狗并列出它们,然后在此基础上,允许另一个未被拒绝的“id”。
我编写的代码的上述部分将包含两部分。 “拒绝”部分和“允许”部分。 Allowed部分必须测试最初未为<deny />
选择的其他“id”。
答案 0 :(得分:2)
您可以反转逻辑并循环遍历第一个文件中的 dog 元素,而不是循环遍历规则元素,首先只选择具有相应< strong>拒绝,然后再次挑选那些没有。
要创建规则元素的外观,您可以定义变量,如此
<xsl:variable name="lookup" select="document('profile.xml')/profile/animal-helper/animal/category/rule" />
要查找被拒绝的 dog 元素,您可以执行此操作(假设您位于第一个文件中的 dog_info 元素)
<xsl:apply-templates select="dog[@id=$lookup[deny]/value]" />
要获得不否认的,只需这样做
<xsl:apply-templates select="dog[not(@id=$lookup[deny]/value)]" />
就“语言”而言,您可以从选择带有所需语言的 dog_info 元素开始
<xsl:apply-templates select="dog_list[@xml:lang='en']" />
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:variable name="lookup" select="document('profile.xml')/profile/animal-helper/animal/category/rule" />
<xsl:template match="/*">
<xsl:apply-templates select="dog_list[@xml:lang='en']" />
</xsl:template>
<xsl:template match="dog_list">
DENY:<br />
<xsl:apply-templates select="dog[@id=$lookup[deny]/value]" />
APPROVE:<br />
<xsl:apply-templates select="dog[not(@id=$lookup[deny]/value)]" />
</xsl:template>
<xsl:template match="dog">
<xsl:value-of select="@name" />
<br />
</xsl:template>
</xsl:stylesheet>
这应输出以下内容
DENY:<br>
Nikki<br>
Zulu<br>
APPROVE:<br>
Tyler<br>
Sally<br>
Joe<br>
答案 1 :(得分:2)
首先:忘记<xsl:for-each>
存在。它使事情变得困难。你(几乎)从不需要它。
编写模板并使用模板匹配,专注于选择节点和将模板应用于,而不是编写嵌套循环。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:variable name="profile" select="document('profile.xml')" />
<xsl:variable name="denied" select="$profile//animal/category/rule[deny]/value" />
<xsl:template match="/*">
<html>
<head><!-- ... --></head>
<body>
<h1>Denied</h1>
<ul>
<xsl:apply-templates select="dog_list/dog[@id = $denied]" />
</ul>
<h1>Allowed</h1>
<ul>
<xsl:apply-templates select="dog_list/dog[not(@id = $denied)]" />
</ul>
</body>
</html>
</xsl:template>
<xsl:template match="dog">
<li><xsl:value-of select="@name" /></li>
</xsl:template>
</xsl:stylesheet>
关于语言和默认语言,使用参数和键:
<xsl:param name="defaultLang" select="'en'" />
<xsl:param name="displayLang" select="'piggylatin'" />
<!-- index dogs by their language and ID -->
<xsl:key name="kDogByLang" match="dog" select="concat(../@xml:lang, '/', @id)" />
<!-- ...and replace the dog template with this: -->
<xsl:template match="dog">
<xsl:variable name="default" select="key('kDogByLang', concat($defaultLang, '/', @id))" />
<xsl:variable name="display" select="key('kDogByLang', concat($displayLang, '/', @id))" />
<xsl:choose>
<!-- if this is the correct language, output it -->
<xsl:when test="generate-id() = generate-id($display)">
<li><xsl:value-of select="$display/@name" /></li>
</xsl:when>
<!-- if this is the default lang (and no correct lang exists), output this -->
<xsl:when test="generate-id() = generate-id($default) and not($display)">
<li><xsl:value-of select="$default/@name" /></li>
</xsl:when>
<!-- there is no "otherwise" - all other cases shall not produce output -->
</xsl:choose>
</xsl:template>
这样,您可以通过传入正确的参数值轻松配置样式表的输出。