XML syntax error on line 9: unescaped < inside quoted string
XML:
<MatchCfg>
<ConfirmTimeOutPunish Time="2" />
<MatchRoom MaxLoop="100" />
<MatchPlayer MaxLoop="100" />
<MatchStatInfo ReportInterval="5"/>
<TABLEAU>
<META>
<MatchMode MissionType="enum<.MissionType>" desc="string">
<Time MinTime="duration" MaxTime="duration" Freq="int" ConfirmTime="int" />
<Open BeginDate="date" BeginTime="time" EndDate="date" EndTime="time" />
<Camp TYPE="repeated" CampID="uint32" PlayerNum="int" desc="string" />
<Strategy StrategyID="enum<.ENMMatchStrategy>" desc="string" />
<Scope ScopeID="enum<.ENMMatchScope>" desc="string" />
<Filter TYPE="repeated" FilterID="enum<.ENMMatchFilter>" Open="bool" Value="int" UpdInterval="duratioin" desc="string">
<Power TYPE="repeated" HornorPower="int">
<Param TYPE="repeated" Value="int"/>
</Power>
</Filter>
<Route Key="int" desc="string" />
<!-- PlayerOnlyOneCamp: 匹配到AI的玩家都在一个阵营 GuaranteeAIRatio:保底AI概率万分比 -->
<MatchAI IsOpen="bool" PlayerOnlyOneCamp="bool" GuaranteeAIRatio="int">
<AI Type="enum<.ENMAIWarmType>" IsOpen="bool" MinTime="duration" MaxTime="duration" desc="string" />
</MatchAI>
<!-- 优先级, 随机模式随机先后顺序的权重,用于控制随机模式各个模式的比例 -->
<Random MissionType="enum<.MissionType>" Priority="int" />
</MatchMode>
</META>
</TABLEAU>
</MatchCfg>
My code:
atom.Log.Debugf("xml: %s", xmlPath)
f, err := os.Open(xmlPath)
if err != nil {
return errors.Wrapf(err, "failed to open %s", xmlPath)
}
p, err := xmlquery.CreateStreamParser(f, "/")
if err != nil {
return errors.Wrapf(err, "failed to create parsee for file %s", xmlPath)
}
n, err := p.Read()
if err != nil {
return errors.Wrapf(err, "failed to read from file %s", xmlPath)
}
root := xmlquery.CreateXPathNavigator(n)
Error:
2022-01-19T14:59:57.061+0800|ERROR|tableau/tableau.go:75|generate failed: XML syntax error on line 14: unescaped < inside quoted string
failed to read from file testdata/xml/match/Match.xml
github.com/Wenchy/tableau/internal/protogen.(*XmlGenerator).convert
/data/home/user00/Git/tableau/internal/protogen/protogen.go:333
github.com/Wenchy/tableau/internal/protogen.(*Generator).convert
/data/home/user00/Git/tableau/internal/protogen/protogen.go:149
github.com/Wenchy/tableau/internal/protogen.(*Generator).generate
/data/home/user00/Git/tableau/internal/protogen/protogen.go:141
github.com/Wenchy/tableau/internal/protogen.(*Generator).generate
/data/home/user00/Git/tableau/internal/protogen/protogen.go:126
github.com/Wenchy/tableau/internal/protogen.(*Generator).Generate
/data/home/user00/Git/tableau/internal/protogen/protogen.go:114
github.com/Wenchy/tableau.Xml2Proto
/data/home/user00/Git/tableau/tableau.go:74
github.com/Wenchy/tableau/test.Test_Xml2Proto
/data/home/user00/Git/tableau/test/tableau_test.go:59
testing.tRunner
/usr/local/go/src/testing/testing.go:1194
runtime.goexit
/usr/local/go/src/runtime/asm_amd64.s:1371
As my point of view, < which is inside quotes should be allowed to construct an attribute value, but the errors above occur. Any way to let me use the characters < and > in attribute values?
In XML, the < character is not allowed in attribute values. You should escape < and > characters to < and > before save XML.
In XML, the
<character is not allowed in attribute values. You should escape<and>characters to<and>before save XML.
The reason why I don't want to use < and > is that those characters are so ugly. It will cause bad readablility for XML users.
@huieric that naturally depends on how you present that data :) You can (and should) always post-process it before showing it to your users...
Anyway, you simply cannot override the XML standard regarding special entities just because the standard doesn't fit your aesthetic concept of 'beauty'. You might dislike the standards, but it's thanks to those standards that there is interoperability.
Note that you can use hexadecimal constants instead of < and > but, then again, these won't look 'nicer', just mor confusing. Also, you can attempt to define your own replacements (see the standards on how to accomplish that), within the limits and guidelines given on that document (no, you cannot redefine < as < and expect it to work; but you might be able to define, say, &left-bracket; to represent &#60; (that's the hex for <). Theoretically, a fully-standards-compliant XML parser ought to be able to deal with that, but, in practice, I wouldn't count on it...
Also, you can always switch to JSON :-) @antchfx's XPath library also works with JSON, and, arguably, JSON is slightly more human-readable than XML, although, on the flip side, JSON does (deliberately) not support the complex schema validation mechanism provided by XML DTDs... but you might not need it for your project.
Last but not least... you can hack this code and supercede the way entity replacements work... but then don't expect the resulting XML to be compatible/readable by anything else out there. That's the price you pay for sidestepping standards...