我有xsl删除所有空标记,但是如果该部分的所有标记都为空,我只想删除空标记。看看我的输入文件,例如:
<NEWORDER>
<ID>1</ID>
<HEADER>
<NMP>NAME PLATE</NMP>
<ORDER>
<USER_ID>USER ID</USER_ID>
<PARTNER_ID>PARTNER ID</PARTNER_ID>
<USER_REFERENCE>5555-55555555-5555</USER_REFERENCE>
<PO_HEADER>
<PO_NUMBER>5555-55555555-5555</PO_NUMBER>
<PO_DATE>20170322</PO_DATE>
<PO_TYPE>BT</PO_TYPE>
<RELEASE_NBR></RELEASE_NBR>
<CUST_ORDER_NBR>5555555555</CUST_ORDER_NBR>
<CONTACT_NAME></CONTACT_NAME>
<CONTACT_PHONE></CONTACT_PHONE>
<TRANS_METHOD></TRANS_METHOD>
<SHIP_COMP>SC</SHIP_COMP>
<CURR_CODE>USD</CURR_CODE>
<INCO_TERMS>FOB</INCO_TERMS>
<NAMED_PLACE></NAMED_PLACE>
<PAYMENT_METHOD>BT</PAYMENT_METHOD>
<TERM_TYPE>555</TERM_TYPE>
<TERM_DESC>NET 10 DAYS</TERM_DESC>
<DEST_BRANCH>5555</DEST_BRANCH>
</PO_HEADER>
<PO_HEADER_NOTES>
<TEXT1_QUAL></TEXT1_QUAL>
<TEXT1_MSG></TEXT1_MSG>
</PO_HEADER_NOTES>
</ORDER>
</HEADER>
</NEWORDER>
在这个例子中,我希望输出只删除&#34; PO_HEADER_NOTES&#34;所有内部标签都是空的部分。预期产出的例子:
<NEWORDER>
<ID>1</ID>
<HEADER>
<NMP>NAME PLATE</NMP>
<ORDER>
<USER_ID>USER ID</USER_ID>
<PARTNER_ID>PARTNER ID</PARTNER_ID>
<USER_REFERENCE>5555-55555555-5555</USER_REFERENCE>
<PO_HEADER>
<PO_NUMBER>5555-55555555-5555</PO_NUMBER>
<PO_DATE>20170322</PO_DATE>
<PO_TYPE>BT</PO_TYPE>
<RELEASE_NBR></RELEASE_NBR>
<CUST_ORDER_NBR>5555555555</CUST_ORDER_NBR>
<CONTACT_NAME></CONTACT_NAME>
<CONTACT_PHONE></CONTACT_PHONE>
<TRANS_METHOD></TRANS_METHOD>
<SHIP_COMP>SC</SHIP_COMP>
<CURR_CODE>USD</CURR_CODE>
<INCO_TERMS>FOB</INCO_TERMS>
<NAMED_PLACE></NAMED_PLACE>
<PAYMENT_METHOD>BT</PAYMENT_METHOD>
<TERM_TYPE>555</TERM_TYPE>
<TERM_DESC>NET 10 DAYS</TERM_DESC>
<DEST_BRANCH>5555</DEST_BRANCH>
</PO_HEADER>
</ORDER>
</HEADER>
</NEWORDER>
我用来删除所有空节点的xsl如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:if test=". != '' or ./@* != ''">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:if>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
<xsl:template match="text() | comment() | processing-instruction()">
<xsl:copy />
</xsl:template>
</xsl:stylesheet>
请指教。任何帮助表示赞赏。
答案 0 :(得分:0)
如果该部分的所有标签都是,我只想删除空标签 空。
这不是一个非常明确的要求。查看给定的示例,它看起来应该重述为:删除(a)有子节点的任何元素,但(b)不包含任何文本节点 - 作为直接子节点或其后代之一的子节点。这将实现为:
XSLT 1.0
x = 0 # empty
x |= 1<<19 # set bit 19
x &= ~(1<<19) # clear bit 19
x ^= 1<<19 # toggle bit 19
x = ~x # invert *all* bits, all the way to infinity
mask = ((1<<20)-1) # define a 20 bit wide mask
x &= mask # ensure bits 20 and higher are 0
x ^= mask # invert only bits 0 through 19
(x >> 19) & 1 # test bit 19
(x >> 16) & 0xf # get bits 16 through 20.
<强>结果强>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[* and not(descendant::text())]"/>
</xsl:stylesheet>
答案 1 :(得分:0)
根据您的要求,以下单个模板似乎符合要求:
请注意,这与您的示例XSLT略有不同 - 对于属性,仅检查元素的属性是否计算为''
,即空字符串。根据我自己的经验,我(很少)遇到元素可能具有空字符串属性的情况,以及需要维护该属性的情况,因此下面的代码通过检查存在来解释>属性的em>,而不仅仅是属性的值。调整以符合您的要求。
<xsl:template match="*">
<xsl:choose>
<!-- Strip only if:
1) Element has children.
2) Nothing in the tree starting here contains any text or attributes. -->
<xsl:when test="./* and not(descendant-or-self::*[text() or @*])"/>
<!-- In all other cases, just copy over, and process children. -->
<xsl:otherwise>
<!-- Copies the element itself. -->
<xsl:copy>
<!-- Copies all attributes, if there are any. -->
<xsl:copy-of select="@*"/>
<!-- Sends any children along for further processing. -->
<xsl:apply-templates/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>