Как ограничить, какие узлы выводят данные в таблице стилей - PullRequest
0 голосов
/ 24 сентября 2011

Я работаю над преобразованием.Цель состоит в том, чтобы преобразовать узлы в пары ключ / значение.Нашел отличную рекомендацию по таблице стилей на этом форуме, но я мог бы использовать некоторую помощь, чтобы немного ее подправить.Для любого узла, у которого нет дочерних элементов, имя узла должно стать значением <name>, а значение должно стать значением <value>.Исходный документ может иметь некоторую иерархическую структуру, но я хочу игнорировать это и возвращать только нижние узлы, преобразованные, конечно.

Вот мои исходные данные:

<?xml version="1.0" encoding="UTF-8"?>
   <objects>
     <Technical_Spec__c>
      <Id>a0e30000000vFmbAAE</Id>
      <F247__c>4.0</F247__c>
      <F248__c xsi:nil="true"/>
      <F273__c>Bronx</F273__c>
...
     </Technical_Spec__c>
   </objects>

Вот таблица стилей:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">   
    <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="*[count(*) = 0]">   
<item>
    <name>
        <xsl:value-of select="name(.)" />
    </name>
    <value>
        <xsl:value-of select="." />
    </value>
</item>
  </xsl:template>
  <xsl:template match="*[count(*) > 0]">  
    <items>
        <xsl:apply-templates/>             
    </items>
  </xsl:template>
</xsl:stylesheet>

DESIRED OUTPUT - Таблица стилей должна преобразовать эти узлы в пары значений ключей, как это:

<items>
  <item>
    <name>F247__c</name>
    <value>4.0</value>
  </item>
  <item>
    <name>F248__c</name>
    <value></value>
  </item>
  <item>
    <name>F273__c</name>
    <value>Bronx</value>
  </item>
...
</items>

CURRENT OUTPUT - Но он создает вложенные элементы 'items' следующим образом:

<items>
  <items>
    <item><name></name><value></value></item>
...
   </items>
</items>

Я понимаю (я думаю), что он соответствует всем родительским узлам, включая верхнийузел 'objects' и вложенный шаблон 'count count 0'.Поэтому я попытался изменить атрибут совпадений, чтобы исключить «объекты» и начать с «Technical_Spec__c» следующим образом (только строки шаблона):

 <xsl:template match="objects/Technical_Spec__c/*">
 <xsl:template match="*[count(*) = 0]">
 <xsl:template match="objects/*[count(*) > 0]">  

На мой взгляд, это говорит: «Первый (основной) шаблон соответствует только узламс родительскими объектами / Tech_Spec '. Второй (внутренний) шаблон соответствует любому узлу без дочерних элементов. Третий (внешний) шаблон сопоставляет узлы с родительскими "объектами" "- что должно ограничивать меня одним.

ВЫХОД ПОСЛЕ ИЗМЕНЕНИЯМАТЧ - Вот что я получаю:

  <?xml version="1.0" encoding="UTF-8"?>
- <items xmlns=""><?xml version="1.0"?>
    <item><name>Id</name><value>a0e30000000vFmbAAE</value></item>
    <item><name>F247__c</name><value>4.0</value></item>
...
</items>

лишний блок <items> пропал, но в середине остался лишний <?xml> блок, поэтому он больше не распознается как действительный xml.

Есть идеи?Почему лишние <?xml>;Как ограничить шаблон определенными частями дерева?

1 Ответ

0 голосов
/ 27 сентября 2011

Путем большого количества проб и ошибок я наткнулся на следующее решение: я добавил корневой якорь к третьему критерию соответствия шаблону.

Вместо match="*[count(*) > 0]" у меня теперь есть /*[count(*) > 0].Похоже, это устраняет внешний элемент <items>.Если кто-нибудь может сказать мне, почему, я был бы признателен.Почему это отличается от /objects/*[count(*) > 0]?

Я действительно думаю, что Димитр прав насчет процессора (это IBM Cast Iron), поэтому я открыл билет.Я тестировал ту же таблицу стилей сверху на онлайн-тестере XSLT и не получил дополнительный тег <?xml ?>.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">   
        <xsl:apply-templates/>
  </xsl:template>
  <xsl:template match="*[count(*) = 0]">   
    <item>
    <name>
        <xsl:value-of select="name(.)" />
    </name>
    <value>
        <xsl:value-of select="." />
    </value>
</item>
  </xsl:template>
  <xsl:template match="/*[count(*) > 0]">  

    <items>
        <xsl:apply-templates/>             
    </items>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...