0

我已经为此工作了一段时间,但无法找到任何类型的工作解决方案。所有这些都在 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进行匹配,获取name和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 表(拒绝部分)的一部分。它应该看起来像这样:

“否认
尼基祖鲁

“允许”
泰勒·
莎莉
·乔

所以“拒绝”找到值 1 和 2,匹配 id 1 和 2,并返回名称。并且“允许”发现 id 3、4、5(因为 1 和 2)被拒绝并返回名称。

<deny />元素的目的是挑选出被拒绝的狗并列出它们,然后基于此,将允许其他未被拒绝的“id”。

我写的代码的上述部分将有两个部分。“拒绝”部分和“允许”部分。Allowed 部分必须测试最初没有为<deny />.

4

2 回答 2

2

您可以反转逻辑并循环遍历第一个文件中的dog元素,而不是循环遍历规则元素,首先选择唯一具有相应拒绝的元素,然后再次选择那些没有的元素。

要创建规则元素的外观,您可以定义一个变量,如下所示

<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>
于 2013-10-27T09:26:06.693 回答
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>

这样,您可以通过传入正确的参数值轻松配置样式表的输出。

示例:http ://www.xmlplayground.com/jv3TvQ

于 2013-10-27T09:55:48.273 回答