XSLT не может преобразовать DITA в новый тип

У меня есть xml следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE concept SYSTEM "aimlDomain.dtd">
<?xml-stylesheet type="text/xsl" href="aimlTest.xsl"?>
<concept>
<category>
   <pattern>_ TOPIC ELEMENT ATTRIBUTE</pattern>
   <template><srai>REQUIRED TOPIC AND MAP ELEMENT ATTRIBUTES</srai> 
   </template>
</category> 
<category>
   <pattern>TOPIC ELEMENT ATTRIBUTE _</pattern>
   <template><srai>REQUIRED TOPIC AND MAP ELEMENT ATTRIBUTES</srai> 
   </template>
</category>
</concept>

Категория элемента — это новый домен, который я добавляю со специализацией элемента, которая специализируется на иностранном элементе. Я хочу преобразовать файл в цель, новый тип преобразования. Ожидаемый результат должен быть таким:

`   <?xml version="1.0" encoding="utf-8"?>
    <category>
      <pattern>_ TOPIC ELEMENT ATTRIBUTE</pattern>
      <template><srai>REQUIRED TOPIC AND MAP ELEMENT ATTRIBUTES</srai> 
      </template>
    </category>`

Но в файле нет ничего, кроме объявления. Фактический вывод выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>

Вот мой файл aimlTest.xsl:

  <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="*[contains(@class, ' topic/topic topic/concept ')]">
    <xsl:for-each select="*[contains(@class, ' topic/foreign category-d/category 
    ')]">
    <xsl:copy-of select="."/>
    </xsl:for-each>
    </xsl:template>
    </xsl:stylesheet>

Я хочу знать, как выбрать ожидаемый контент.


person Maggie Chen    schedule 11.12.2018    source источник
comment
В вашем XML нет элемента с атрибутом class, поэтому ничего не выбирается. -- У вас есть два почти одинаковых элемента category; почему копируется только один/   -  person michael.hor257k    schedule 11.12.2018
comment
Каждый элемент в DITA имеет класс атрибутов по умолчанию, но я не знаю, как его отобразить.   -  person Maggie Chen    schedule 11.12.2018
comment
Правильно ли определены атрибуты @class в вашем DTD? Правильно ли загружено DTD? Вы запускаете трансформацию через соответствующий плагин DITA-OT?   -  person potame    schedule 11.12.2018
comment
Обратите внимание, что ваше выражение contains, вероятно, должно быть contains(' topic/topic topic/concept ', @class), хотя само по себе я не думаю, что это решит вашу проблему.   -  person Tim C    schedule 11.12.2018
comment
Вот мой тестовый код в Git: github.com/ant28/aimlTest. Я пробовал много методов, но я все еще не решил это.   -  person Maggie Chen    schedule 11.12.2018


Ответы (1)


Есть много посторонних факторов, которые усложняют это. Один сопоставляется с атрибутом @class вместо имен элементов. Поэтому я сделал упрощенную версию, см. ниже.

Вот входной файл DITA, который я использовал (я удалил DTD и XSLT PI, потому что они мне не нужны для этого примера):

<?xml version="1.0" encoding="utf-8"?>
<concept>
  <category>
    <pattern>_ TOPIC ELEMENT ATTRIBUTE</pattern>
    <template>
      <srai>REQUIRED TOPIC AND MAP ELEMENT ATTRIBUTES</srai>
    </template>
  </category>
  <category>
    <pattern>TOPIC ELEMENT ATTRIBUTE _</pattern>
    <template>
      <srai>REQUIRED TOPIC AND MAP ELEMENT ATTRIBUTES</srai>
    </template>
  </category>
</concept>

Вот XSLT, который я использовал, совпадающий только по именам элементов:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="concept">
    <root>
      <xsl:for-each select="category">
        <xsl:copy-of select="."/>
      </xsl:for-each>
    </root>
  </xsl:template>
</xsl:stylesheet>

Я добавил корневой элемент (названный <root>, имя может быть любым) в XSLT, чтобы на выходе был правильный XML.

И вот результат:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <category>
    <pattern>_ TOPIC ELEMENT ATTRIBUTE</pattern>
    <template>
      <srai>REQUIRED TOPIC AND MAP ELEMENT ATTRIBUTES</srai>
    </template>
  </category>
  <category>
    <pattern>TOPIC ELEMENT ATTRIBUTE _</pattern>
    <template>
      <srai>REQUIRED TOPIC AND MAP ELEMENT ATTRIBUTES</srai>
    </template>
  </category>
</root>

Если вы хотите, вы можете реорганизовать его, чтобы использовать сопоставление атрибутов @class, но я подозреваю, что вам это не нужно. Если вам это нужно, сначала убедитесь, что ваше DTD правильно добавляет атрибуты класса. В DITA DTD атрибуты класса установлены "по умолчанию", что означает, что они включены в каждый экземпляр XML, даже если они не присутствуют в XML буквально (синтаксис см. в DITA DTD). В целях публикации OT DITA запускает предварительный процесс над XML-файлами DITA, который извлекает все атрибуты @class по умолчанию перед запуском XSLT. Тогда XML выглядит примерно так:

<concept class=" topic/concept ">
  <category class=" topic/foreign category-d/category ">
    <pattern class=" etc ">_ TOPIC ELEMENT ATTRIBUTE</pattern>
    <template class=" etc ">
      <srai>REQUIRED TOPIC AND MAP ELEMENT ATTRIBUTES</srai>
    </template>
  </category>
[...]

И тогда ваш исходный XSLT может соответствовать атрибутам класса. Есть веская причина DITA для сопоставления этих атрибутов @class, но вам может не понадобиться это делать, и вы добавляете сложности, пытаясь это сделать.

person markg    schedule 11.12.2018
comment
Спасибо, попробовал ваш метод в DITA-OT, но ничего не вышло. Как вы разбираете файл? - person Maggie Chen; 14.12.2018
comment
Я запускал его вне DITA OT, используя только XSLT-процессор. Попробуйте это из командной строки: <dita-ot>\lib\java -jar Saxon-HE-9.8.0-12.jar -s:path-to-dita.dita -xsl:path-to-xslt.xsl -o:output-file.xml -- вам нужна Java в командной строке. Возможно, придется изменить имя файла jar Saxon. Используйте мои файлы выше. - person markg; 14.12.2018
comment
Спасибо большое! Попробовал ваш метод, работает! Но у меня есть другая проблема, что я получаю невыбранный контент в файле. Из-за ограниченного места я публикую свой код в группе пользователей Google DITA-OT: groups.google.com/forum/#!topic/dita-ot-users/n1LeaHb3PtI. Большое спасибо. - person Maggie Chen; 14.12.2018