我的xml类似于:
<?xml version="1.0" encoding="UTF-8"?>
<Invoice
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ccts="urn:un:unece:uncefact:documentation:2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 2.1\maindoc\UBL-Invoice-2.1.xsd">
<cbc:UBLVersionID>2.1</cbc:UBLVersionID>
<cbc:CustomizationID>2.0</cbc:CustomizationID>
<cbc:ID>FB98-00396</cbc:ID>
<cbc:IssueDate>2018-06-15</cbc:IssueDate>
<cac:Signature>
<cbc:ID>FB98-00396</cbc:ID>
<cac:SignatoryParty>
<cac:PartyIdentification>
<cbc:ID>20338570041</cbc:ID>
</cac:PartyIdentification>
<cac:PartyName>
<cbc:Name>
<![CDATA[UBL]]>
</cbc:Name>
</cac:PartyName>
</cac:SignatoryParty>
<cac:DigitalSignatureAttachment>
<cac:ExternalReference>
<cbc:URI>FB98-00396</cbc:URI>
</cac:ExternalReference>
</cac:DigitalSignatureAttachment>
</cac:Signature>
</Invoice>
这是我上面验证XML的xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
version="2.0">
<xsl:include href="error_utils.xsl" dp:ignore-multiple="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:include href="error_utils.xsl" dp:ignore-multiple="yes" />
<xsl:template match="/*">
<xsl:apply-templates select="@*|node()" />
.......//more code here
</xsl:template>
<xsl:template name="existAndRegexpValidateElement">
<xsl:param name="errorCodeNotExist" />
<xsl:param name="errorCodeValidate" />
<xsl:param name="node" />
<xsl:param name="regexp" />
<xsl:param name="isError" select="true()"/>
<xsl:param name="descripcion" select="'Error Expr Regular'"/>
<xsl:choose>
<xsl:when test="not(string($node))">
<xsl:choose>
<xsl:when test="$isError">
<xsl:call-template name="rejectCall">
<xsl:with-param name="errorCode" select="$errorCodeNotExist" />
<xsl:with-param name="errorMessage" select="concat($descripcion,': ', $errorCodeNotExist,' (nodo: "',name($node/parent::*),'/', name($node), '" valor: "', $node, '")')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="addWarning">
<xsl:with-param name="warningCode" select="$errorCodeNotExist" />
<xsl:with-param name="warningMessage" select="concat($descripcion,': ', $errorCodeNotExist,' (nodo: "',name($node/parent::*),'/', name($node), '" valor: "', $node, '")')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:if test='not(matches($node,$regexp))'>
<xsl:choose>
<xsl:when test="$isError">
<xsl:call-template name="rejectCall">
<xsl:with-param name="errorCode" select="$errorCodeValidate" />
<xsl:with-param name="errorMessage" select="concat($descripcion,': ', $errorCodeValidate,' (nodo: "',name($node/parent::*),'/', name($node), '" valor: "', $node, '")')" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="addWarning">
<xsl:with-param name="warningCode" select="$errorCodeValidate" />
<xsl:with-param name="warningMessage" select="concat($descripcion,': ', $errorCodeValidate,' (nodo: "',name($node/parent::*),'/', name($node), '" valor: "', $node, '")')" />
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
当我申请验证时,我得到了:
Error at char 2 in xsl:apply-templates/@select on line ....
XTDE0420: Cannot create an attribute node (xsi:schemaLocation) whose parent is a document
node. Most recent element start tag was output at line -1 of module *unknown*
at xsl:apply-templates (file:///home/.....)
processing /Invoice/@xsi:schemaLocation
in built-in template rule
这似乎是因为xsi:schemaLocation =“urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 2.1 \ maindoc \ UBL-Invoice-2.1.xsd”在身份模板上:
<xsl:apply-templates select="@*|node()" />
因为当我从XML中删除xsi:schemaLocation =“urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 2.1 \ maindoc \ UBL-Invoice-2.1.xsd”时,它没有任何错误。
我做错了什么?
答案 0 :(得分:2)
使用模板
<xsl:template match="/*">
<xsl:apply-templates select="@*|node()" />
.......//more code here
</xsl:template>
您处理根元素并仅转换其属性和子节点,但不复制根元素。由于您的根元素有一个属性xsi:schemaLocation
,并且您为属性提供的模板是属性转换,该属性被复制到结果树,但该尝试会给您带来错误,因为您无法将任何属性节点附加到文档节点,您只能将其附加到元素节点。
目前尚不清楚您想要实现的目标以及为什么需要匹配/*
的模板,但如果要复制根元素的属性,则需要确保复制根元素以及例如xsl:copy
或者在创建不同的元素节点后处理其属性。