xml в обычный текст с использованием xsl без жесткого кодирования - PullRequest
1 голос
/ 08 мая 2020

Я преобразовал XML в обычный текст с помощью xsl, я хочу вывести текст узлов и его атрибутов. Я хочу, чтобы xsl был generi c, без имени узла. Мне это удалось. Но когда у меня есть пустой узел в xml, он будет записан на выходе. Я не хочу этого. Как я могу перестать писать пустой узел или атрибут с помощью xsl? Я ищу реализацию, в которой проверяется не имя узла, а все узлы.

У меня есть следующие XML.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<run xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <tests>
        <test name="a" attr1="" attr2="" attr3="an_value">
            <usecase name="name1">
                <description>Some description</description>
            </usecase>
            <usecase name="name2">
                <description>Descripton1</description>
            </usecase>
            <usecase name="name3">
                <description>Descripton2</description>
            </usecase>
        </test>
    </tests>
    <vip>
        <file name="b">
            <stat wins="1"/>
            <justifications/>
        </file>
        <file name="c">
            <stat wins="2" />
            <justifications/>
        </file>
    </vip>
</run>

У меня есть следующие XSL.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>


  <xsl:strip-space elements="*"/>
    <xsl:template match="node()"> 
<xsl:value-of select="local-name()"/> 
  <xsl:text> </xsl:text>
    <xsl:value-of select="text()" />
        <xsl:call-template name="attributes"/> 
  <xsl:text>
  </xsl:text>
      <xsl:apply-templates select=" node()"/>
  </xsl:template>


  <xsl:template name="attributes">
  <xsl:for-each select="@*">
<xsl:value-of select="local-name()"/> 
  <xsl:text> : </xsl:text>
    <xsl:value-of select="."/>
  <xsl:text> </xsl:text>
  </xsl:for-each>
  </xsl:template>


  </xsl:stylesheet>

Вывод:

run 
  tests 
  test name : a attr1 :  attr2 :  attr3 : an_value 
  usecase name : name1 
  description Some description

  usecase name : name2 
  description Descripton1

  usecase name : name3 
  description Descripton2

  vip 
  file name : b 
  stat wins : 1 
  justifications 
  file name : c 
  stat wins : 2 
  justifications 

какую команду xsl я могу использовать, чтобы не отображать выравнивание узлов и атрибуты attr1 и attr2, если все они пусты без жесткого кодирования xsl?

Желаемый результат

run 
  tests 
  test name : a attr3 : an_value 
  usecase name : name1 
  description Some description

  usecase name : name2 
  description Descripton1

  usecase name : name3 
  description Descripton2

  vip 
  file name : b 
  stat wins : 1 

  file name : c 
  stat wins : 2 

РЕДАКТИРОВАТЬ: Я обновил xsl до этого

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="no"/>
    <xsl:variable name="empty_string" select="''" />

  <xsl:strip-space elements="*"/>
    <xsl:template match="node()"> 
                <xsl:value-of select="local-name()"/> 
                  <xsl:text> </xsl:text>
                    <xsl:value-of select="text()" />
                    <xsl:call-template name="attributes"/> 
                  <xsl:text>
                  </xsl:text>
      <xsl:apply-templates select=" node()"/>
  </xsl:template>


  <xsl:template name="attributes">
  <xsl:for-each select="@*">
            <xsl:if test="normalize-space(.) != $empty_string">
            <xsl:value-of select="local-name()"/> 
              <xsl:text> : </xsl:text>
                <xsl:value-of select="."/>
              <xsl:text> </xsl:text>
       </xsl:if>
  </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Я все еще ищу условие, чтобы не писать узел, если он не имеет атрибуты и никакие дочерние элементы. В этом случае узел согласования отображаться не будет.

Ответы [ 2 ]

1 голос
/ 08 мая 2020

Пример несколько неоднозначен, и лог c, который необходимо здесь применить, не совсем ясен. Я предполагаю, что вы хотите сделать что-то вроде:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>

<xsl:template match="*[@*|node()]"> 
    <xsl:value-of select="name()"/> 
    <xsl:text> </xsl:text>
    <xsl:apply-templates select="@*[string()]|text()"/> 
    <xsl:text>&#10;</xsl:text>
    <xsl:apply-templates select="*"/> 
</xsl:template>

<xsl:template match="@*"> 
    <xsl:value-of select="name()"/> 
    <xsl:text> : </xsl:text>
    <xsl:value-of select="."/>
    <xsl:text> </xsl:text>
</xsl:template>

</xsl:stylesheet>

Лично я бы не стал использовать пробел в качестве разделителя, потому что он может легко появиться как часть значения (как и перевод строки, на самом деле).

0 голосов
/ 08 мая 2020

Вот как это можно сделать:

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

  <xsl:output method="text"/>

  <xsl:template match="node()">
    <xsl:if test="text() or node() or @*">
      <xsl:text>&#xa;</xsl:text>
      <xsl:value-of select="local-name()"/>
      <xsl:text> </xsl:text>
      <xsl:value-of select="normalize-space(text())"/>
    </xsl:if>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:if test=".!=''">
      <xsl:value-of select="local-name()"/>
      <xsl:text> : </xsl:text>
      <xsl:value-of select="."/>
      <xsl:text> </xsl:text>
    </xsl:if>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:template>

</xsl:stylesheet>

Посмотрите, как это работает: https://xsltfiddle.liberty-development.net/bEzknt1/1

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