2013-09-30 6 views
0

У меня есть следующий XML-файл:XML для преобразования XML: гнездовые подобные узлы

<ref> 
<m-citation> 
<string-name> 
<surname>Carey</surname>, <given-names>J.W.</given-names> 
</string-name>, <string-name> 
<surname>Wigand</surname>, <given-names>M.</given-names> 
</string-name>, <string-name> 
<surname>Can</surname>, <given-names>S.J.</given-names> 
</string-name>, 
<year>2007</year>. <source>xyz</source>, <volume>1</volume>, <f>75</f>-<l>85</l>. 
</m-citation> 
</ref> 

нужно преобразовать это:

<ref> 
<m-citation> 
<publisher> 
<name> 
<surname>Carey</surname><given-names>J.W.</given-names> 
</name>, <name> 
<surname>Wigand</surname><given-names>M.</given-names> 
</name>, <name> 
<surname>Can</surname><given-names>S.J.</given-names> 
</name>, 
</publisher> 
<year>2007</year>. <source>xyz</source>, <volume>1</volume>, <f>75</f>-<l>85</l>. 
</m-citation> 
</ref> 

Обратите внимание: изменения 'строка имя_файла' на «имя ', все элементы «string-name» вложены в элемент «издатель» и запятая после того, как фамилия не будет сохранена. Пробовал разные способы, но не смог получить точный результат. Помощь любого рода была бы оценена по достоинству. Благодарю.

Я написал следующий код:

<xsl:template match="m-citation"> 
<xsl:element name="m-citation"> 

<xsl:element name="publisher"> 
<xsl:for-each select="string-name[position() &lt;= last()]"> 
<xsl:element name="name"> 
<xsl:element name="surname"> 
<xsl:value-of select="surname"/> 
</xsl:element> 
<xsl:element name="given-names"> 
<xsl:value-of select="given-names"/> 
</xsl:element> 
</xsl:element><xsl:text>, </xsl:text> 
</xsl:for-each> 
</xsl:element> 

<xsl:apply-templates/> 

</xsl:element> 
</xsl:template> 


<xsl:template match="ref//year"> 
<xsl:element name="year"> 
<xsl:apply-templates/> 
</xsl:element> 
</xsl:template> 

<xsl:template match="ref//source"> 
<xsl:element name="source"> 
<xsl:apply-templates/> 
</xsl:element> 
</xsl:template> 

Аналогично для элементов объема, ф и л.

Я получаю следующий результат:

<ref> 
<m-citation> 
<publisher> 
<name> 
<surname>Carey</surname><given-names>J.W.</given-names> 
</name>, <name> 
<surname>Wigand</surname><given-names>M.</given-names> 
</name>, <name> 
<surname>Can</surname><given-names>S.J.</given-names> 
</name>, 
</publisher> ,,, 
<year>2007</year>. <source>xyz</source>, <volume>1</volume>, <f>75</f>-<l>85</l>. 
</m-citation> 
</ref> 

, как я использую применить-шаблонов запятые после имя-строки (которые находятся вне все дочерние элементы) которые будут отображаться (,,,). Извините за ошибки, если они есть в приведенных выше строках кода. Урезали его здесь и там.

+0

Вы говорите, что вы пробовали разные способы. Можете ли вы поделиться тем, что было ближе всего к тому, чего вы хотели достичь? – rene

+0

Можете ли вы опубликовать то, что вы пробовали? Мы не хотим предлагать области, которые вы уже тестировали. – Gusdor

+0

В ваших примерах есть некоторые проблемы с закрывающими тегами. Думаю, это не проблема. Что касается ответа XSLT: просто сопоставьте тег ref. , и адаптировать остальное с написанием некоторых xml-элементов и копированием содержимого тега, который вы хотите переименовать. – Matthias

ответ

0

Это XSLT-таблица стилей:

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

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

    <!-- At m-citation, put in the publisher element then apply templates to all string-name 
     elements, and to all text nodes that have a string-name element after them. 
     Outside the publisher element, apply templates to everything else. --> 
    <xsl:template match="m-citation"> 
    <xsl:copy> 
     <publisher> 
     <xsl:apply-templates select="string-name | text()[count(following-sibling::string-name) &gt; 0]"/> 
     </publisher> 
     <xsl:apply-templates select="node()[not(self::string-name) and count(following-sibling::string-name) = 0]"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- Replace string-name with name then apply-templates to its children. --> 
    <xsl:template match="string-name"> 
    <name> 
     <xsl:apply-templates select="@*|node()"/> 
    </name> 
    </xsl:template> 

    <!-- Remove the first text node that comes after surname (a comma in your particular 
     input. --> 
    <xsl:template match="text()[preceding-sibling::*[1][self::surname]]"/> 

</xsl:stylesheet> 

, когда применяется к следующим входным XML:

<ref> 
    <m-citation> 
    <string-name> 
     <surname>Carey</surname>, <given-names>J.W.</given-names> 
    </string-name>, <string-name> 
     <surname>Wigand</surname>, <given-names>M.</given-names> 
    </string-name>, <string-name> 
     <surname>Can</surname>, <given-names>S.J.</given-names> 
    </string-name> 
    <year>2007</year>. <source>xyz</source> <volume>1</volume> <f>75</f> <l>85</l>. 
    </m-citation> 
</ref> 

производит следующий вывод:

<ref> 
    <m-citation><publisher> 
    <name> 
     <surname>Carey</surname><given-names>J.W.</given-names> 
    </name>, <name> 
     <surname>Wigand</surname><given-names>M.</given-names> 
    </name>, <name> 
     <surname>Can</surname><given-names>S.J.</given-names> 
    </name></publisher> 
    <source>xyz</source> <volume>1</volume> <f>75</f> <l>85</l>. 
    </m-citation> 
</ref> 

, который не довольно отформатирован так, как вы хотите, но я думаю, что контент все там правильно.

+0

Это то, что я хотел. Просто нужно спросить вас, что, если мы не знаем, какой элемент произошел после «». Это не обязательно «год». – GTM

+0

То есть правило, которое '' должно появиться после последнего элемента 'name'? –

+0

Последний элемент 'name' должен заканчиваться на' ', что абсолютно нормально.Но следующий элемент может не обязательно быть «годом» (согласно вашему коду). 'Source',' volume' или, если это произойдет, любой допустимый элемент может появиться после окончания 'издателя'. – GTM

0

Со следующим XSLT элемент string-name будет переведен в name, а элемент publisher будет добавлен. Все остальные элементы и значения копируются:

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

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

    <xsl:template match="m-citation"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*" /> 

      <publisher> 
       <xsl:apply-templates select="string-name" /> 
      </publisher> 

      <xsl:apply-templates select="node()[not(self::string-name)]" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="string-name"> 
     <name> 
      <xsl:apply-templates select="@*|node()" /> 
     </name> 
    </xsl:template> 
</xsl:stylesheet> 
+0

Это не удерживает пунктуации, которые я предполагаю: GTM

+0

Если вы измените это на '', он сохранит пунктировку –

+0

Та же проблема, что и в моем коде. Также отображаются запятые после имени строки. В этом случае ",,,". – GTM

Смежные вопросы