Переименуйте имя узла с P и добавьте атрибут как и старое имя

Я пытаюсь преобразовать xml в HTML-теги для Google Translate API в groovy. Поскольку Google переводит не html-теги, я хочу переместить тег xml в качестве имени атрибута и имя тега как «p». Я создал следующий XML из данных, которые у меня есть.

<root>
   <glossary>
      <GlossDiv>
         <GlossList>
                  <element>
                  <GlossEntry>
                     <Abbrev>ISO 8879:1986</Abbrev>
                     <GlossDef>
                        <GlossSeeAlso>
                           <element>
                              <element>GML</element>
                              <element>XML</element>
                           </element>
                        </GlossSeeAlso>
                        <para>A meta-markup language, used to create markup languages such as DocBook.</para>
                     </GlossDef>
                     <GlossSee>markup</GlossSee>
                     <GlossTerm>Standard Generalized Markup Language</GlossTerm>
                  </GlossEntry>
               </element>
               </GlossList>
      </GlossDiv>
   </glossary>

Но я хочу вывести, как показано ниже:

<p id="root">
   <p id="glossary">
      <p id="GlossDiv">
         <p id="GlossList">
                  <p id="element">
                  <p id="GlossEntry">
                     <p id="Abbrev">ISO 8879:1986</p>
                     <p id="GlossDef">
                        <p id="GlossSeeAlso">
                           <p id="element">
                              <p id="element">GML</p>
                              <p id="element">XML</p>
                           </p>
                        </p>
                        <p id="para">A meta-markup language, used to create markup languages such as DocBook.</p>
                     </p>
                     <p id="GlossSee">markup</p>
                     <p id="GlossTerm">Standard Generalized Markup Language</p>
                  </p>
               </p>
               </p>
      </p>
   </p>

И как только я получу переведенный контент из API Google, я хочу преобразовать его обратно в исходный формат XML. Я пробовал различные коды groovy и java для этого, но я не могу проанализировать XML, как ожидалось.

Кто-нибудь может помочь?


person Akshay Chavan    schedule 10.08.2018    source источник
comment
Я бы, наверное, просто использовал регулярное выражение: def newXml = oldXml.replaceAll(/<(\w+)>/, ) { all, group -> "<p id='$group'>" }.replaceAll(/<\/(\w+)>/, ) { all, group -> "</p>" }   -  person MushyPeas    schedule 10.08.2018
comment
Это сработало как шарм. Можете ли вы помочь мне с обратным отображением. Я плохо разбираюсь в регулярных выражениях.   -  person Akshay Chavan    schedule 10.08.2018
comment
что вы подразумеваете под обратным сопоставлением, если вы имеете в виду значение регулярных выражений, просто проверьте regex101.com, вы получите подробные объяснения: regex101.com/r/8hIZ5D/1   -  person MushyPeas    schedule 10.08.2018
comment
Я хочу, чтобы сгенерированный вывод был преобразован обратно в исходный формат, как только я получу переведенный текстовый контент. т. е. формат ‹root›‹root›.   -  person Akshay Chavan    schedule 10.08.2018
comment
вернуться назад намного сложнее, вы можете использовать это, но это больше похоже на хак, а не на красивое def lastTag def oldXml = newXml.replaceAll(/p(?: id=")?(?<tag>\w+)?"?>/, { all, group -> lastTag = (group) ? group : lastTag return "${lastTag}>" })   -  person MushyPeas    schedule 10.08.2018


Ответы (1)


Для этого вы можете использовать XSLT (расширяемые преобразования языка таблиц стилей).

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

    <xsl:template match="/">
        <xsl:for-each select="*">
            <xsl:call-template name="p_template"/>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="p_template">
        <p>
            <xsl:attribute name="id">
                <xsl:value-of select="name(.)"/>
            </xsl:attribute>
            <xsl:for-each select="text()">
                <xsl:value-of select="normalize-space(.)"/>
            </xsl:for-each>
            <xsl:call-template name="repeat"/>
        </p>
    </xsl:template>

    <xsl:template name="repeat">
        <xsl:for-each select="./*">
            <xsl:call-template name="p_template"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

Для обратного вы можете использовать его:

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

    <xsl:template match="/">
        <xsl:for-each select="*">
            <xsl:call-template name="reverse_template"/>
        </xsl:for-each>
    </xsl:template>

    <xsl:template name="reverse_template">
        <xsl:element name="{@id}">
            <xsl:value-of select="text()"/>
            <xsl:call-template name="repeat"/>
        </xsl:element>

    </xsl:template>

    <xsl:template name="repeat">
        <xsl:for-each select="./*">
            <xsl:call-template name="reverse_template"/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>
person Anton Petrov    schedule 10.08.2018
comment
Это отлично работает!! Мне нужна одна модификация выше xslt. Я хотел бы добавить префикс к имени узла 11_11_{NodeName} в качестве идентификатора Google Translate для html-контента, который я только что обнаружил. Также удалите этот префикс при обратном отображении. Можете подсказать как это сделать. - person Akshay Chavan; 10.08.2018