Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用xsl将xml转换为纯文本,无需硬编码_Xml_Xslt - Fatal编程技术网

使用xsl将xml转换为纯文本,无需硬编码

使用xsl将xml转换为纯文本,无需硬编码,xml,xslt,Xml,Xslt,我已经使用xsl将XML转换为纯文本,我想输出节点的文本和属性。我希望xsl是通用的,不包含节点的名称。我设法做到了。但是当我有一个xml中的空节点时,它将被写入输出中。我不想那样。如何停止使用xsl写入空节点或属性?我正在寻找一种实现,它不检查节点的名称,而是检查所有节点 我有以下XML <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <run xmlns:xsi="http://www.w3.org/2001/

我已经使用xsl将XML转换为纯文本,我想输出节点的文本和属性。我希望xsl是通用的,不包含节点的名称。我设法做到了。但是当我有一个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命令不显示节点对正以及属性attr1和attr2(如果它们都为空)

期望输出

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>

: 

我仍然在寻找一个条件,如果节点没有属性和子节点,就不写它。在这种情况下,将不显示对齐节点。

该示例有点含糊不清,此处需要应用的逻辑也不完全清楚。我猜你想做一些类似的事情:

XSLT1.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>



: 

就个人而言,我不会使用空格作为分隔符,因为它可以很容易地显示为值的一部分(实际上,换行符也是如此)。

以下是一种方法:

<?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>


;
: 

查看此处的工作情况:

文本值的结果应该是什么?类似于:test attr2:attr value为什么应该排除
“text value”
?我的问题。不应排除任何内容,仅当属性为空且节点没有子项或属性时才应使用排除,在其余情况下,我们提取所有数据。test attr2:attr value text value类似于此。此示例仅用于测试。其思想是,它可以是具有任何模式的xml,只有节点和属性中的数据才能复制为纯文本。空格部分是因为最初情况更糟。使用您的解决方案,不再写入空属性,这比我最初的解决方案有了很大的改进。我尝试了您的解决方案,但您丢失了描述,空对正节点仍然存在。@BlajBogdan我更新了我的答案,它现在应该符合您的需要。
<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>
<?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>