Переместите определенные узлы, которые являются родственными узлами выбранного узла, в новый родительский узел. - PullRequest
1 голос
/ 02 марта 2011

Я провел здесь поиск и нашел несколько вопросов, которые были связаны с моей проблемой, но у меня все еще проблемы ... (надеюсь, что все нормально, я добавляю новый вопрос вместо того, чтобы комментировать существующий). )

<?xml version="1.0"?>
<section>
    <title>Main Section</title>
    <para>Here is some text that is a child of a main section.</para>
    <para>Some more text.</para>
    <para>When a section has subsections, it should not have loose paragraphs before the first sub section. Those loose paras should be placed inside a comment element.</para>
    <section>
        <title>This is my subsection</title>
        <para>Text that is inside of the sub-section</para>
        <para>And some more sub section text.</para>
    </section>
</section>

Я хочу, чтобы / section / para был помещен во вновь созданный узел комментариев, например:

<?xml version="1.0"?>
<section>
    <title>Main Section</title>
    <comment>
       <para>Here is some text that is a child of a main section.</para>
       <para>Some more text.</para>
       <para>When a section has subsections, it should not have loose paragraphs before the first sub section. Those loose paras should be placed inside a comment element.</para>
    </comment>
    <section>
        <title>This is my subsection</title>
        <para>Text that is inside of the sub-section</para>
        <para>And some more sub section text.</para>
    </section>
</section>

Я попробовал некоторые предложения, которые нашел при поиске в стеке, самый близкий из них здесь.

Это таблица стилей, которую я использую:

<?xml version='1.0'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>


<xsl:template match="node()|@*" name="identity">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>


<!-- paras that are children of a section that has direct para children and dircect section children -->
<xsl:template match="section[para][section]/para[1]">
    <comment>
        <xsl:apply-templates select="../para" mode="commentPara"/>

    </comment>
</xsl:template>

<xsl:template match="*" mode="commentPara">
    <xsl:call-template name="identity"/>
</xsl:template>

<xsl:template match="section[para][section]/para"/>


</xsl:stylesheet>

Это выводит это:

<?xml version='1.0' ?>
<section>
    <title>Main Section</title>



    <section>
        <title>This is my subsection</title>
        <para>Text that is inside of the sub-section</para>
        <para>And some more sub section text.</para>
    </section>
</section>

просто удаляя пункты, которые я хочу обернуть в тег комментария. Я пытался по существу проходить построчно таблицу стилей в вопросе, с которым я связан ... есть идеи? Спасибо, п.о.

Ответы [ 2 ]

3 голосов
/ 02 марта 2011

Это группировка смежных para элементов.

Проблема в Разрешение конфликтов для правил шаблона : потому что оба para правила соответствия имеют одинаковый приоритет импорта и одинаковый вычисленный приоритет, механизм восстановления после ошибки может привести к применению последнего.

Вам необходимо явно определить @priority в правиле "first para child", например:

<xsl:template match="section[para][section]/para[1]" priority="1">
</

При такой модификации выдается:

<?xml version="1.0" encoding="UTF-16"?>
<section>
    <title>Main Section</title>
    <comment>
        <para>Here is some text that is a child of a main section.</para>
        <para>Some more text.</para>
        <para>When a section has subsections, it should not have loose paragraphs before the first sub section. Those loose paras should be placed inside a comment element.</para>
    </comment>
    <section>
        <title>This is my subsection</title>
        <para>Text that is inside of the sub-section</para>
        <para>And some more sub section text.</para>
    </section>
</section>
1 голос
/ 02 марта 2011

Я бы сделал это так :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kPreceding" match="para"
  use="generate-id(following-sibling::section[1])"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="section[preceding-sibling::para]">
  <comment>
   <xsl:apply-templates mode="copy"
        select="key('kPreceding', generate-id())"/>
  </comment>

  <xsl:call-template name="identity"/>
 </xsl:template>

 <xsl:template match=
  "para[following-sibling::section]"/>

 <xsl:template match="para" mode="copy">
  <xsl:call-template name="identity"/>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к предоставленному документу XML:

<section>
    <title>Main Section</title>
    <para>Here is some text that is a child of a main section.</para>
    <para>Some more text.</para>
    <para>When a section has subsections, it should not have loose paragraphs before the first sub section. Those loose paras should be placed inside a comment element.</para>
    <section>
        <title>This is my subsection</title>
        <para>Text that is inside of the sub-section</para>
        <para>And some more sub section text.</para>
    </section>
</section>

желаемый, правильный результат получается:

<section>
   <title>Main Section</title>
   <comment>
      <para>Here is some text that is a child of a main section.</para>
      <para>Some more text.</para>
      <para>When a section has subsections, it should not have loose paragraphs before the first sub section. Those loose paras should be placed inside a comment element.</para>
   </comment>
   <section>
      <title>This is my subsection</title>
      <para>Text that is inside of the sub-section</para>
      <para>And some more sub section text.</para>
   </section>
</section>

Объяснение

  1. Правило идентификации (шаблон) копирует каждый узел "как есть".

  2. Шаблон переопределения для section, который имеет предшествующих братьев и сестер para, оборачивает всех таких братьев и сестер элементом comment, а затем вызывает преобразование идентичности для себя.

  3. Для удобства мы определяем ключ, который соответствует всем para элементам, предшествующим элементу section, с заданным generate-id().

  4. Элементы para, имеющие следующий брат section, исключаются из действия правила идентификации с помощью переопределенного шаблона, который просто ничего не делает.

  5. Наконец, такие para элементы при выводе в оболочку comment обрабатываются в режиме copy, который просто вызывает правило идентификации для выполнения копирования.

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